Ext.ns('Ufida', 'Ufida.offline', 'Ufida.data', 'Ufida.excel', 'Ufida.menu',
		'Ufida.ui', 'Ufida.grid', 'Ufida.i18n', 'Ufida.output');

//////////////////////////////////////////开始常用参数///////////////////////////////////
Ext.isIE8 = /msie 8/.test(navigator.userAgent.toLowerCase());
var isAir = false;
Ufida.PRICE_DECIMAL = 4;
Ufida.QTY_DECIMAL = 4;
Ufida.AMT_DECIMAL = 2;
Ufida.RATE_DECIMAL = 7;

// 弹出况类型
Ufida.Client = "Client";
Ufida.Provider = "Provider";
Ufida.Employee = "Employee";
Ufida.Stock = "Stock";
Ufida.Measurement = "Measurement";
Ufida.StoreRoom = "StoreRoom";
Ufida.SubBankAccount = "SubBankAccount";
Ufida.RPReason = "RPReason";
Ufida.BankAccount = "BankAccount";

// 自定义项种类
Ufida.StockCustom = "0";
Ufida.ClientCustom = "1";
Ufida.ProviderCustom = "2";
Ufida.PurOrderCustom = "3";
Ufida.PurInOrderCustom = "4";
Ufida.SaleOrderCustom = "5";
Ufida.SaleOutOrderCustom = "6";

//根据这个全局变量判断页面的货品明细是否可以重复
Ufida.GOODSNUM_UNIQUE = false;
// 单据列表仓库权限查询标识，query代表仓库有编辑和查询的权限。
Ufida.QUERYTYPE = "query";
// 在列表中区分编辑、查看、新增的链接
Ufida.EDIT = "edit";
Ufida.ADD = "add";
Ufida.VIEW = "view";

//////////////////////////////////结束常用参数///////////////////////////////////////////////////

/** 
 * inline tip  --tongliang 20091010 BEGIN
 */
Ext.override(Ext.QuickTip,{ 
	showDelay : 300,
    hideDelay : 300,
	afterRender : function(){
        Ext.QuickTip.superclass.afterRender.call(this);
        var evtName = 'mousedown' ;
        this.el.on(evtName,function(e){
        	var t = Ext.fly(this.triggerEl)
        	e.target = this.triggerEl;
        	var grid = t.findParentNode('.x-grid-panel',200,true);
        	if(grid){
	        	grid = Ext.getCmp(grid.id)
	        	grid.processEvent('mousedown',e)
	        	grid.processEvent('mouseup',e)
	        	grid.processEvent('click',e)
        	}else{
			    try{
			    	var tree = t.findParentNode('.x-tree',200,true);
				    tree = Ext.getCmp(tree.id);
    	    		var treeNode =  t.findParentNode('.x-tree-node-el',100,true);
        			var id = treeNode.getAttributeNS('ext','tree-node-id');
	        	    treeNode = tree.getNodeById(id);
        			treeNode.ownerTree.fireEvent('click',treeNode,e)
			    }catch(ex){}
        	}
        	this.delayHide();
        	
        	
        },this);
        this.el.on("mousewheel",function(e){
        	this.ensureHide();
        },this);
//        	this.on('show',function(){
//        		debug(' tip show ,trigger.id= '+this.triggerEl.id)
//        	})
    },
    ensureHide : function(){
    	this.clearTimer('show');
    	this.hide();
    },
	onTargetOver : function(e){
        if(this.disabled){
            return;
        }
        this.targetXY = e.getXY();
        var t = e.getTarget();
        if(this.el && e.within(this.el)){
        	e.stopPropagation();
			this.clearTimer('hide')
        	return;
        }
        // 保存出现tip的html元素的引用  inline tips -- tongliang1010
        if(t.id!=this.id){
        	this.triggerEl = t ;	
        }
        if(!t || t.nodeType !== 1 || t == document || t == document.body){
            return;
        }
        if(this.activeTarget && t == this.activeTarget.el){
            this.clearTimer('hide');
            this.delayShow();
            return;
        }
        if(t && this.targets[t.id]){
            this.activeTarget = this.targets[t.id];
            this.activeTarget.el = t;
            this.delayShow();
            return;
        }
        var ttp, et = Ext.fly(t), cfg = this.tagConfig;
        var ns = cfg.namespace;
        if(this.interceptTitles && t.title){
            ttp = t.title;
            t.qtip = ttp;
            t.removeAttribute("title");
            e.preventDefault();
        } else{
            ttp = t.qtip || et.getAttributeNS(ns, cfg.attribute);
        }
        if(ttp){
            var autoHide = et.getAttributeNS(ns, cfg.hide);
            this.activeTarget = {
                el: t,
                text: ttp,
                width: et.getAttributeNS(ns, cfg.width),
                autoHide: autoHide != "user" && autoHide !== 'false' ,
                title: et.getAttributeNS(ns, cfg.title),
                cls: et.getAttributeNS(ns, cfg.cls),
                align: et.getAttributeNS(ns, cfg.align)
            };
            this.delayShow();
        }
    }
})
Ext.override(Ext.tree.TreeNodeUI,{
	renderElements : function(n, a, targetNode, bulkRender){
        // add some indent caching, this helps performance when rendering a large tree
        this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
        var cb = typeof a.checked == 'boolean';
        var href = a.href ? a.href : Ext.isGecko ? "" : "#";
        var buf = ['<li class="x-tree-node"><div ext:tree-node-id="',n.id,'" class="x-tree-node-el x-tree-node-leaf x-unselectable ', a.cls,'" unselectable="on">',
            '<span class="x-tree-node-indent">',this.indentMarkup,"</span>",
            '<img src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" />',
            '<img src="', a.icon || this.emptyIcon, '" class="x-tree-node-icon',(a.icon ? " x-tree-node-inline-icon" : ""),(a.iconCls ? " "+a.iconCls : ""),'" unselectable="on" />',
            cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '',
            '<a hidefocus="on" class="x-tree-node-anchor" href="',href,'" tabIndex="1" ',
             a.hrefTarget ? ' target="'+a.hrefTarget+'"' : "", '><span onmouseover=Ufida.checkTreeTip(this); unselectable="on">',n.text,"</span></a></div>",
            '<ul class="x-tree-node-ct" style="display:none;"></ul>',
            "</li>"].join('');
        var nel;
        if(bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())){
            this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf);
        }else{
            this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);
        }
        
        this.elNode = this.wrap.childNodes[0];
        this.ctNode = this.wrap.childNodes[1];
        var cs = this.elNode.childNodes;
        this.indentNode = cs[0];
        this.ecNode = cs[1];
        this.iconNode = cs[2];
        var index = 3;
        if(cb){
            this.checkbox = cs[3];
			// fix for IE6
			this.checkbox.defaultChecked = this.checkbox.checked;			
            index++;
        }
        this.anchor = cs[index];
        this.textNode = cs[index].firstChild;
    }
});
Ext.override(Ext.grid.EditorGridPanel,{
	initEvents : function(){
        Ext.grid.EditorGridPanel.superclass.initEvents.call(this);
        this.on("bodyscroll", this.stopEditing, this, [true]);
        if(this.clicksToEdit == 1){
            this.on("cellclick", this.onCellDblClick, this);
        }else {
            if(this.clicksToEdit == 'auto' && this.view.mainBody){
                this.view.mainBody.on("mousedown", this.onAutoEditClick, this);
            }
            this.on("celldblclick", this.onCellDblClick, this);
        }
        this.getGridEl().addClass("xedit-grid");
        this.on('beforeedit',function(){
        	if(Ext.QuickTips.isEnabled()){
        		var tip = Ext.QuickTips.getQuickTip() ;
        		if( tip.triggerEl && this.view.mainBody.contains(tip.triggerEl)){
        			setTimeout(function(){
        				tip.ensureHide();
        			},200);
        		}
        	}
        })
    }
});
/** 
 * inline tip  --tongliang 20091010 END
 */

/**
 * @param excelkey
 *            业务名称
 * @param cm
 *            列定�?
 * @param ds
 *            数据存储�?
 * @param start
 *            分页起始�?
 * @param limit
 *            分页大小
 */
Ufida.excel.toExcel = function(key, cm, ds, start, limit) {
	if (ds.getTotalCount() == 0) {
		displayMessageBox('提示', '导出数据为空。');
		return;
	}else if(ds.getTotalCount()>65535){
		Ext.MessageBox.confirm('提示', '导出数据量过大,可能会导出失败,是否继续?', function(btn) {
			if (btn == 'yes') {
				// Http请求URL
				var HttpURL = ds.proxy.url;
				// Http请求参数
				var params = {} ;
				Ext.apply(params,ds.baseParams);
				
				// 取得列数
				var columnCount = cm.getColumnCount();
				// excel列标题数组
				var headers = []
				// excel列数据数组
				var idxs = []
				for (var i = 0; i < columnCount; i++) {
					// 列标题
					var columnHeader = cm.getColumnHeader(i);
					// 列数据
					var dataIndex = cm.getDataIndex(i);
					// 隐藏列
					var isColumnHidden = cm.isHidden(i);
			//		alert(columnHeader+","+dataIndex+","+isColumnHidden)
					if (!isColumnHidden) {
						if (dataIndex) {
							// 将列数据放入excel列数据数组
							idxs.push(dataIndex);
							// 将列标题放入excel列标题数组
							headers.push(encodeURIComponent(Ext.util.Format.stripTags(columnHeader)))
						}
					}
				}
				Ext.apply(params,{
					format 	: 'excel',
					start	: start || 0,
					exportAllFields:true,
					limit 	: limit || ds.getTotalCount(),
					headers : headers.join(",") ,
					idxs 	: idxs.join(","),
					excelkey: key 
				});
				var url = HttpURL+"&"+Ext.urlEncode(params);	
				var opener= new Ufida.WindowOpenFun();
		        opener.windowOpen(url,null,null,"export.xls");
			}
		});
	}else{
		// Http请求URL
		var HttpURL = ds.proxy.url;
		// Http请求参数
		var params = {} ;
		Ext.apply(params,ds.baseParams);
		
		// 取得列数
		var columnCount = cm.getColumnCount();
		// excel列标题数组
		var headers = []
		// excel列数据数组
		var idxs = []
		for (var i = 0; i < columnCount; i++) {
			// 列标题
			var columnHeader = cm.getColumnHeader(i);
			// 列数据
			var dataIndex = cm.getDataIndex(i);
			// 隐藏列
			var isColumnHidden = cm.isHidden(i);
	//		alert(columnHeader+","+dataIndex+","+isColumnHidden)
			if (!isColumnHidden) {
				if (dataIndex) {
					// 将列数据放入excel列数据数组
					idxs.push(dataIndex);
					// 将列标题放入excel列标题数组
					headers.push(encodeURIComponent(Ext.util.Format.stripTags(columnHeader)))
				}
			}
		}
		Ext.apply(params,{
			format 	: 'excel',
			start	: start || 0,
			exportAllFields:true,
			limit 	: limit || ds.getTotalCount(),
			headers : headers.join(",") ,
			idxs 	: idxs.join(","),
			excelkey: key 
		});
		var url = HttpURL+"&"+Ext.urlEncode(params);	
		
		var opener= new Ufida.WindowOpenFun();
		opener.windowOpen(url,null,null,"export.xls");
	}
	
}

Ufida.excel.toPDF = function(key, cm, ds, start, limit, company) {
	if (ds.getTotalCount() == 0) {
		displayMessageBox('提示', '导出数据为空。');
		return;
	}else if(ds.getTotalCount()>65535){
		Ext.MessageBox.confirm('提示', '导出数据量过大,可能会导出失败,是否继续?', function(btn) {
			if (btn == 'yes') {
				// Http请求URL
				var HttpURL = ds.proxy.url;
				var params = {} ;
				Ext.apply(params,ds.baseParams);
				
				// 取得列数
				var columnCount = cm.getColumnCount();
				// excel列标题数组
				var headers = []
				// excel列数据数组
				var idxs = []
			
				for (var i = 0; i < columnCount; i++) {
					// 列标题
					var columnHeader = cm.getColumnHeader(i);
					// 列数据
					var dataIndex = cm.getDataIndex(i);
					// 隐藏列
					var isColumnHidden = cm.isHidden(i);
			
					if (!isColumnHidden ) {			
						if (dataIndex) {
							// 将列数据放入excel列数据数组
							idxs.push(dataIndex);
							// 将列标题放入excel列标题数组
							headers.push(encodeURIComponent(Ext.util.Format.stripTags(columnHeader)))
						}
					}
				}
				Ext.apply(params,{
					format 	: 'pdf',
					exportAllFields:true,
					start	: start || 0,
					limit 	: limit || ds.getTotalCount(),
					headers : headers.join(",") ,
					idxs 	: idxs.join(","),
					key		: key ,
					company : company
				});
				var url = HttpURL+"&"+Ext.urlEncode(params);
				var opener= new Ufida.WindowOpenFun();
		        opener.windowOpen(url,null,null,"export.pdf");
			}
		});
	}else{
		// Http请求URL
		var HttpURL = ds.proxy.url;
		var params = {} ;
		Ext.apply(params,ds.baseParams);
		
		// 取得列数
		var columnCount = cm.getColumnCount();
		// excel列标题数组
		var headers = []
		// excel列数据数组
		var idxs = []
	
		for (var i = 0; i < columnCount; i++) {
			// 列标题
			var columnHeader = cm.getColumnHeader(i);
			// 列数据
			var dataIndex = cm.getDataIndex(i);
			// 隐藏列
			var isColumnHidden = cm.isHidden(i);
	
			if (!isColumnHidden ) {			
				if (dataIndex) {
					// 将列数据放入excel列数据数组
					idxs.push(dataIndex);
					// 将列标题放入excel列标题数组
					headers.push(encodeURIComponent(Ext.util.Format.stripTags(columnHeader)))
				}
			}
		}
		Ext.apply(params,{
			format 	: 'pdf',
			exportAllFields:true,
			start	: start || 0,
			limit 	: limit || ds.getTotalCount(),
			headers : headers.join(",") ,
			idxs 	: idxs.join(","),
			key		: key ,
			company : company
		});
		var url = HttpURL+"&"+Ext.urlEncode(params);
		var opener= new Ufida.WindowOpenFun();
		        opener.windowOpen(url,null,null,"export.xls");
	}
}

/**
 * PagingToolbarExt.js
 */
Ext.PagingToolbarExt = Ext.extend(Ext.PagingToolbar, {

			initComponent : function() {
				Ext.PagingToolbarExt.superclass.initComponent.apply(this,
						arguments);
			},
			onRender : function(ct, position) {
				Ext.PagingToolbarExt.superclass.onRender.call(this, ct,
						position);

				this.addButton({
					split:true,
					scope:this,
					text : '导出 Excel',
					pressed : false,
					menu : new Ext.menu.Menu({
						items : [{
							text : '导出当前页 Excel',
							handler : this.onClick2.createDelegate(this,
									["printCurrent"])
						}, {
							text : '导出全部 Excel',
							handler : this.onClick2.createDelegate(this, ["printAll"])
						}]
					}),
					handler :this.onClick2.createDelegate(this,
									["printCurrent"])
				});
				this.addButton({
					split:true,
					scope:this,
					text : '导出 pdf',
					pressed : false,
					menu : new Ext.menu.Menu({
						items : [{
							text : '导出当前页  pdf',
							handler : this.onClick2.createDelegate(this,
									["printCurrentPDF"])
						}, {
							text : '导出全部 pdf',
							handler : this.onClick2.createDelegate(this, ["printAllPDF"])
						}]
					}),
					handler :this.onClick2.createDelegate(this,
									["printCurrentPDF"])
				});
				
				 
			},
			onClick2 : function(which) {
				var ds = this.store;
				var cm = this.cm;
				switch (which) {
					case "printCurrent" :
						Ufida.excel.toExcel(this.id, cm, ds, this.cursor,
								this.pageSize);
						break;

					case "printAll" :
						Ufida.excel.toExcel(this.id, cm, ds);
						break;

					case "printCurrentPDF" :
						Ufida.excel.toPDF(this.id, cm, ds, this.cursor,
								this.pageSize);
						break;

					case "printAllPDF" :
						Ufida.excel.toPDF(this.id, cm, ds);
						break;
				}
			},
			doLoad : function(start) {
				this.cursor = start;
				Ext.PagingToolbarExt.superclass.doLoad.apply(this, arguments)
			}
		});

/**
 * 
 * PagingToolbarExt.js
 */

Ufida.ui.size = {
	// Popup Window Size
	POP_WIN_WIDTH : 800,
	POP_WIN_HEIGHT : 500,

	// Popup Window Form Size
	POP_WIN_FORM_WIDTH : 500,
	POP_WIN_FORM_HEIGHT : 450,

	// GAP
	HORIZONTAL_GAP : 8,
	VERTICAL_GAP : 8,
	// 3 panel view
	SPLIT_LEFT_WIDTH : 175,
	SPLIT_LEFT_WIDTH2 : 220,
	SPLIT_LEFT_TOP_HEIGHT : 140,
	SPLIT_LEFT_TOP_HEIGHT3 : 180,
	SPLIT_LEFT_TOP_HEIGHT4 : 200,
	SPLIT_LEFT_TOP_HEIGHT5 : 250,
	SPLIT_LEFT_BOTTOM_HEIGHT : 290,
	SPLIT_LEFT_TOP_HEIGHT2 : 400,
	SPLIT_LEFT_BOTTOM_HEIGHT2 : 140,
	SPLIT_LEFT_PANE_WIDTH : 182,
	SPLIT_LEFT_PANE_WIDTH2 : 222,
	SPLITTER_WIDTH : 8,
	SPLIT_RIGHT_WIDTH : 782,
	SPLIT_LEFT_HEIGHT : 483,
	SPLIT_RIGHT_HEIGHT : 490,
	RIGHT_PANE_STYLE : 'margin-left:8px',
	SPLIT_HEIGHT : 558,
	TREE_HEIGHT : 368,
	SINGLE_PANEL_WIDTH : 950
};

/**
 * ImageItem.js
 */
Ufida.menu.ImageItem = function(conf) {
	this.src = conf['src'];
	this.itemStyle = conf['itemStyle'];
	Ufida.menu.ImageItem.superclass.constructor.call(this);
};

Ext.extend(Ufida.menu.ImageItem, Ext.menu.BaseItem, {
			/**
			 * @cfg {String} src the image path for this item (defaults to '')
			 */
			/**
			 * @cfg {Boolean} hideOnClick True to hide the containing menu after
			 *      this item is clicked (defaults to false)
			 */
			hideOnClick : false,
			/**
			 * @cfg {String} itemCls The default CSS class to use for text items
			 *      (defaults to "x-menu-text")
			 */
			itemCls : "u-menu-igm",

			// private
			onRender : function() {
				var s = document.createElement("img");
				s.className = this.itemCls;
				Ext.DomHelper.applyStyles(s, this.itemStyle)
				s.src = this.src;
				this.el = s;
				Ext.menu.TextItem.superclass.onRender.apply(this, arguments);
			}
		});
Ext.reg('tbimg', Ufida.menu.ImageItem);
/**
 * ImageItem.js
 */

/**
 * 对Ext.MessageBox进行封装，实现统�?调用、统�?外观控制
 * 
 * @param {}
 *            title
 * @param {}
 *            msg
 */
function displayMessageBox(title, msg, buttons, fn) {
	if (fn) {
		Ext.MessageBox.show({
			width : 240,
			// minWidth : 240,
			title : title,
			msg : msg,
			buttons : buttons,
			fn : fn,
			// 加入消息框模式化：不能对消息框以外的区域做操�?
			modal : true
		});
	} else {
		Ext.MessageBox.show({
			width : 240,
			title : title,
			msg : msg,
			buttons : Ext.MessageBox.OK,
			modal : true
		});
	}
};

Ufida.offline.tables = {
	'FlagOnlineOrOffline' : ['accountBook', 'loginName', {
		name : 'Timestamp',
		type : 'int'
	}],
	'DataBaseStatus' : ['status', 'accountBook', 'loginName', {
		name : 'Timestamp',
		type : 'int'
	}],
	'GearsGetAllStocks' : ['stockID', 'stockCode', 'stockName',
			'classificationID', 'classificationCode', 'classificationName',
			'spec', 'measurementPlanCode', 'measurementPlanName',
			'subjectCode', 'subjectName', 'maxQty', 'miniQty', 'retailPrice',
			'purchasePrice', 'tradePrice1', 'tradePrice2', 'tradePrice3',
			'remark', 'pic', 'mnemonic', 'basePerCode', 'basePerName',
			'statPerCode', 'statPerName', 'statChangeRate', 'purPerCode',
			'purPerName', 'purChangeRate', 'salePerCode', 'salePerName',
			'saleChangeRate', 'storePerCode', 'storePerName',
			'storeChangeRate', {
				name : 'balance',
				type : 'float'
			}, 'cost', 'storeroomNum', 'accountBook', 'loginName', {
				name : 'Timestamp',
				type : 'int'
			}],
	'GearsGetStockTree' : ['id', 'text', 'leaf', 'parent', 'accountBook',
			'loginName', {
				name : 'Timestamp',
				type : 'int'
			}],
	'GearsGetStockTreeRelation' : ['stockId', 'classificationId',
			'relationshipId', 'accountBook', 'loginName', {
				name : 'Timestamp',
				type : 'int'
			}],
	'GearsGetAllStoreRoom' : ['storeroomId', 'storeroomCode', 'storeroomName',
			'provinceId', 'provinceName', 'cityId', 'cityName', 'addr',
			'adminId', 'adminName', 'remark', 'accountBook', 'loginName', {
				name : 'Timestamp',
				type : 'int'
			}],
	'GearsGetAllSRtype' : ['srId', 'accountbookId', 'srCode', 'srName',
			'srDirection', 'subjectCode', 'subjectName', 'accountBook',
			'loginName', {
				name : 'Timestamp',
				type : 'int'
			}],
	'GearsGetAllPurchaseOrder' : ['orderId', 'supplierCode', 'supplierName',
			'orderCode', 'empName', 'orderDate', 'accountPeriod', 'limitDate',
			'remark', 'status', 'createPerson', 'createDate', 'rate',
			'accountBook', 'loginName','preferences', {
				name : 'Timestamp',
				type : 'int'
			}],
	'GearsGetAllPurchaseOrderDetail' : ['orderId', 'itemId', 'stockId',
			'stockCode', 'stockName', 'spec', 'basePer', {
				name : 'qty',
				type : 'float'
			}, {
				name : 'uninputQty',
				type : 'float'
			}, 'changePer', 'changeRate', {
				name : 'price',
				type : 'float'
			}, {
				name:'initPrice',
				type : 'float'
			},
			{
				name : 'amt',
				type : 'float'
			}, {
				name : 'taxRate',
				type : 'float'
			}, {
				name : 'tax',
				type : 'float'
			}, 'createPerson', 'createDate', 'useYn', 'accountBook',
			'loginName', {
				name : 'Timestamp',
				type : 'int'
			}],
	'PurchaseOrderDetail4SaveDtail' : ['Rid', 'ModifyId', 'stockMacAccId',
			'ishanItemId', 'itemId', 'stockId', 'stockCode', 'stockName',
			'spec', 'basePer', {
				name : 'qty',
				type : 'float'
			}, {
				name : 'price',
				type : 'float'
			}, {
				name:'initPrice',
				type : 'float'
			}, 'changePer', 'changeRate', {
				name : 'amt',
				type : 'float'
			}, {
				name : 'taxRate',
				type : 'float'
			}, {
				name : 'tax',
				type : 'float'
			}, 'sourceBillItemId', 'accountBook', 'loginName', {
				name : 'Timestamp',
				type : 'int'
			}],
	'PurchaseOrderDetail4SaveHead' : ['Rid', 'purCode', 'purId',
			'supplierCode', 'supplierName', 'contactPerson', 'contanttel',
			'addr', 'empCode', 'empName', 'storeroomCode', 'storeroomName',
			'sourceBillCode', 'purDate', 'purType', 'srCode', 'srName',
			'remark', 'unNormalClose', 'payBillId', 'clearingId', 'payAccount',
			'clearingBillNum', 'payBillAmount', 'ishanId', 'accountPeriod',
			'limitDate', 'preferences', 'voucherId', 'autoVoucher', 'accountBook',
			'loginName', {
				name : 'Timestamp',
				type : 'int'
			}],
	'GearsGetHaveFinanceService' : ['flag', 'success', 'accountBook',
			'loginName', {
				name : 'Timestamp',
				type : 'int'
			}],
	'GearsGetAllpayAccount' : ['id', 'accName', 'accType', 'accountBook',
			'loginName', {
				name : 'Timestamp',
				type : 'int'
			}],
	'GearsGetAllSaleOrder' : ['saleorderId', 'saleorderNum', 'clientNum',
			'clientName', 'busspeoNum', 'busspeoName', 'deliverDate',
			'orderDate', 'accountPeriod', 'limitDate', 'note', 'doformPeo',
			'doformDate', 'totalAmount', 'totalPrice', 'state', 'boxId',
			'rate', 'accountBook', 'loginName', 'preferences', {
				name : 'Timestamp',
				type : 'int'
			}],
	'GearsGetAllSaleOrderDetail' : ['saleorderdetailId', 'saleorderId',
			'goodsNum', 'goodsName', 'standard', 'measureUnit', {
				name : 'amount',
				type : 'float'
			}, {
				name : 'unAmount',
				type : 'float'
			}, {
				name : 'unsegoodsAmount',
				type : 'float'
			}, 'beforeDiscount', {
				name : 'discountRate',
				type : 'float'
			}, {
				name : 'discountPrice',
				type : 'float'
			}, {
				name : 'afterDiscount',
				type : 'float'
			}, {
				name : 'price',
				type : 'float'
			}, {
				name : 'baseUnitNum',
				type : 'float'
			}, 'baseUnitName', {
				name : 'changeRate',
				type : 'float'
			}, {
				name : 'costPrice',
				type : 'float'
			}, 'accountBook', 'loginName', {
				name : 'Timestamp',
				type : 'int'
			}],
	'SaleOrderDetail4SaveDetail' : ['Rid', 'salesenretorddetId', 'goodsNum',
			'goodsName', 'standard', 'measureUnit', {
				name : 'saleorderAmount',
				type : 'float'
			}, {
				name : 'amount',
				type : 'float'
			}, {
				name : 'eachPrice',
				type : 'float'
			}, {
				name : 'price',
				type : 'float'
			}, {
				name : 'costPrice',
				type : 'float'
			}, {
				name : 'texRate',
				type : 'float'
			}, {
				name : 'texPrice',
				type : 'float'
			}, {
				name : 'contexPrice',
				type : 'float'
			}, 'tostoreroomdetId', 'stockId', 'baseUnitNum', 'baseUnitName',
			'changeRate', 'accountBook', 'loginName', {
				name : 'Timestamp',
				type : 'int'
			}],
	'SaleOrderDetail4SaveHead' : ['Rid', 'salesenretorderId', 'saleorderId',
			'salesendNum', 'clientNum', 'clientName', 'contactPerson',
			'contanttel', 'addr', 'accountPeriod', 'limitDate', 'preferences', 'busspeoNum',
			'busspeoName', 'saleDate', 'sourceNum', 'storeroomNum',
			'storeroomName', 'totalAmount', 'totalPrice', 'note',
			'invoiceType', 'tostoreroomId', 'voucherId', 'voucherCostId',
			'totalTexPrice', 'isAutoVoucher', 'accountBook', 'loginName', {
				name : 'Timestamp',
				type : 'int'
			}],
	'GearsGetAllStoreroomNum' : ['storeroomCode', {
		name : 'qty',
		type : 'float'
	}, 'stockCode', 'accountBook', 'loginName', {
		name : 'Timestamp',
		type : 'int'
	}],

	'GearsGetAllStoreroomAdmin' : ['operaterName', 'storeroomId', 'authority',
			'accountbookId', 'accountBook', 'loginName', {
				name : 'Timestamp',
				type : 'int'
			}],

	'GearsGetAllEmployee' : ['id', 'number', 'uunumber', 'imnumber', 'name',
			'dept', 'job', 'isBusinesser', 'zone', 'tel', 'phone', 'email',
			'accountbookId', 'bankCategory', 'bank', 'bankAccountName',
			'account', 'nouse', 'accountBook', 'loginName', {
				name : 'Timestamp',
				type : 'int'
			}],
	'GearsGetAllProvider' : ['no', 'id', 'name', 'clerkid', 'contactPerson','subject',
			'contanttel', 'addr', 'tel', 'accountBook', 'loginName', {
				name : 'Timestamp',
				type : 'int'
			}],
	'GearsGetAllClient' : ['id', 'no', 'name', 'contactPerson', 'contanttel','subject',
			'addr', 'tel', 'businesser', 'businesserNo', 'accountBook',
			'loginName', {
				name : 'Timestamp',
				type : 'int'
			}],
	'GearsGetItemsByOrder' : ['itemId', 'stockCode', 'stockName', 'spec',
			'basePer', {
				name : 'qty',
				type : 'float'
			}, {
				name : 'uninputQty',
				type : 'float'
			}, {
				name : 'price',
				type : 'float'
			}, 'changePer', {
				name : 'changeRate',
				type : 'float'
			}, {
				name : 'amt',
				type : 'float'
			}, 'createPerson', 'createDate', 'useYn', 'accountBook',
			'loginName', {
				name : 'Timestamp',
				type : 'int'
			}],
	'GearsGetBankAcc' : ['id', 'bankType', 'province', 'city', 'bankName',
			'accountName', 'account', 'supplyerId', 'accountBook', 'loginName',
			{
				name : 'Timestamp',
				type : 'int'
			}],
	'GearsGetAllSubject' : ['id', 'no', 'text', 'pid', 'assisAccount', 'leaf',
			'accountBook', 'loginName', {
				name : 'Timestamp',
				type : 'int'
			}],
	'GearsGetModelDetail' : ['summary', 'subject', 'id', 'accountBook',
			'loginName', {
				name : 'Timestamp',
				type : 'int'
			}],
	'GearsGetAllTemplet' : ['id', 'tplName', 'accountBook', 'loginName', {
		name : 'Timestamp',
		type : 'int'
	}],
	'GearsGetAllSummary' : ['id', 'content', 'accountBook', 'loginName', {
		name : 'Timestamp',
		type : 'int'
	}],
	'GearsGetType' : ['id', 'name', 'accountBook', 'loginName', {
		name : 'Timestamp',
		type : 'int'
	}],
	'voucherGetTime' : ['maxVal', 'minVal', 'accountBook', 'loginName', {
		name : 'Timestamp',
		type : 'int'
	}],
	'GearsDemo4Save' : ['id', 'writtenPerson', 'accessoryNo', 'type',
			'voucherDate', 'voucherNo', 'billId', 'billNo', 'source',
			'jfTotal', 'rndId', 'accountBook', 'loginName', {
				name : 'Timestamp',
				type : 'int'
			}],
	'GearsDemo4SaveSummary' : ['summary', 'subject', {
		name : 'jfMoney',
		type : 'FLOAT'
	}, {
		name : 'dfMoney',
		type : 'FLOAT'
	}, 'client', 'provider', 'item', 'goods', 'amount', 'price', 'clearing',
			'clBill', 'id', 'rndId', 'accountBook', 'loginName', {
				name : 'Timestamp',
				type : 'int'
			}],
	'GearsGetAllSubjectParent' : ['id', 'no', 'text', 'pid', 'leaf',
			'accountBook', 'loginName', {
				name : 'Timestamp',
				type : 'int'
			}],
	'GearsGetCurrentPeriod' : ['currentPeriod', 'success', 'accountBook',
			'loginName', {
				name : 'Timestamp',
				type : 'int'
			}],
	'GearsGetOplSwitch' : ['oplswitch', 'accountBook', 'loginName', {
		name : 'Timestamp',
		type : 'int'
	}],
	'GearsGetItem' : ['dept', 'endDate', 'id', 'itemName', 'startDate',
			'accountBook', 'loginName', {
				name : 'Timestamp',
				type : 'int'
			}]

};

Ufida.offline.switch_proxy = function(store, options) {

	if (typeof(isOffline) != 'undefined') {
		if (isOffline) {
			store.proxy = store.offProxy;
		} else {
			store.proxy = store.onProxy
		}
	} else {
		store.proxy = store.onProxy
	}
	return true;
};

Ufida.get_form_values = function(form) {
	var ret = {}
	form.cascade(function(comp) {
		if (comp.id && comp.getValue) {
			ret[comp.id] = comp.getValue()
		}
	})
	return ret
};

Ufida.each_pair = function(hash, fn, scope) {
	for (var key in hash) {
		if (fn.call(scope || hash, key, value, hash) === false) {
			return key;
		};
	}
};

/*Ext.Ajax.on('beforerequest', function(conn, options) {
			p = options.params
			if (typeof p == 'string') {
				options.params = Ext.urlDecode(p)
			}
		}, this)*/;

Ufida.ui.CustomNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {
	// subtract the n's text to fit the widget size
	renderElements : function(n, a, targetNode, bulkRender) {
		a.qtip = n.text
		var text = n.text
		if (n.text.length > 10) {
			var indentMarkup = n.parentNode
					? n.parentNode.ui.getChildIndent()
					: '';
			text = n.text.slice(0, 10) + "..."
		}

		// add some indent caching, this helps performance when
		// rendering a large tree
		this.indentMarkup = n.parentNode
				? n.parentNode.ui.getChildIndent()
				: '';

		var cb = typeof a.checked == 'boolean';

		var href = a.href ? a.href : Ext.isGecko ? "" : "#";
		var buf = [
				'<li class="x-tree-node"><div ext:tree-node-id="',
				n.id,
				'" class="x-tree-node-el x-tree-node-leaf x-unselectable ',
				a.cls,
				'" unselectable="on">',
				'<span class="x-tree-node-indent">',
				this.indentMarkup,
				"</span>",
				'<img src="',
				this.emptyIcon,
				'" class="x-tree-ec-icon x-tree-elbow" />',
				'<img src="',
				a.icon || this.emptyIcon,
				'" class="x-tree-node-icon',
				(a.icon ? " x-tree-node-inline-icon" : ""),
				(a.iconCls ? " " + a.iconCls : ""),
				'" unselectable="on" />',
				cb
						? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked
								? 'checked="checked" />'
								: '/>'))
						: '',
				'<a hidefocus="on" class="x-tree-node-anchor" href="', href,
				'" tabIndex="1" ',
				a.hrefTarget ? ' target="' + a.hrefTarget + '"' : "",
				'><span unselectable="on">', text, "</span></a></div>",
				'<ul class="x-tree-node-ct" style="display:none;"></ul>',
				"</li>"].join('');

		var nel;
		if (bulkRender !== true && n.nextSibling
				&& (nel = n.nextSibling.ui.getEl())) {
			this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf);
		} else {
			this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);
		}

		this.elNode = this.wrap.childNodes[0];
		this.ctNode = this.wrap.childNodes[1];
		var cs = this.elNode.childNodes;
		this.indentNode = cs[0];
		this.ecNode = cs[1];
		this.iconNode = cs[2];
		var index = 3;
		if (cb) {
			this.checkbox = cs[3];
			// fix for IE6
			this.checkbox.defaultChecked = this.checkbox.checked;
			index++;
		}
		this.anchor = cs[index];
		this.textNode = cs[index].firstChild;
	}
});

// Ext.tree.TreeNode.prototype.defaultUI = Ufida.ui.CustomNodeUI;

function RndNum(n) {
	var rnd = "";
	for (var i = 0; i < n; i++)
		rnd += Math.floor(Math.random() * 10);
	return rnd;
}


/*******************************************************************************
 * 在window窗口上增加按esc退出的提示,windowTip的css在finance.css里配置
 ******************************************************************************/
Ext.override(Ext.Window, {
			modal : true,
			resizable : false,
			escTitle : "按Esc退出",
			setEscTitle : function(title, iconCls) {
				if (this.header && this.headerAsText) {
					var a = this.header.createChild({
								cls : "windowTip"
							}, this.header.child('span').dom);
					a.update(title);
				}
				if (iconCls) {
					this.setIconClass(iconCls);
				}
				this.fireEvent('titlechange', this, title);
				return this;
			},
			show : function(animateTarget, cb, scope) {
				if (!this.rendered) {
					this.render(Ext.getBody());
				}
				if (this.hidden === false) {
					this.toFront();
					return;
				}
				if (this.fireEvent("beforeshow", this) === false) {
					return;
				}
				if (cb) {
					this.on('show', cb, scope, {
								single : true
							});
				}
				this.hidden = false;
				if (animateTarget !== undefined) {
					this.setAnimateTarget(animateTarget);
				}
				this.beforeShow();
				if (this.animateTarget) {
					this.animShow();
				} else {
					this.afterShow();
				}
				if (this.escTitle && !this.escVisible) {
					this.escVisible = true;
					this.setEscTitle(this.escTitle);
				} else {
					this.header.down(".windowTip").update(this.escTitle);
				}
				if (!this.tools.close.isVisible()) {
					this.header.down(".windowTip").update("");
				}
				this.getKeyMap().enable();
			}
		});

/*******************************************************************************
 * 在window窗口上增加按esc退出的提示结束
 ******************************************************************************/

Ufida.offline._confirm = function() {

	// var _status =
	// window.parent.document.getElementById('hiddenButton').value;
	//
	// return _status;
};
Ufida.excel.toExcel4Substance = function(excelkey, cm, ds, start, limit, cm2,
		ds2) {
	// var headersL = []
	// var idxsL = []
	//
	// var headersR = []
	// var idxsR = []
	var headers = []
	var idxs = []
	for (var i = 0; i < cm.getColumnCount(); i++) {
		// 取得列标??
		var columnHeader = cm.getColumnHeader(i);
		// 取得列数??
		var dataIndex = cm.getDataIndex(i);
		// 取得列隐藏标??
		var isColumnHidden = cm.isHidden(i);

		if (isColumnHidden) {
			// 隐藏的列不导??
		} else {
			if (dataIndex) {
				// idxs.push(dataIndex);
				headers.push(encodeURIComponent(Ext.util.Format
						.stripTags(columnHeader)))
			}
		}
	}

	// ==========================================================
	for (var i = 0; i < cm2.getColumnCount(); i++) {
		// 取得列标??
		var columnHeader = cm2.getColumnHeader(i);
		// 取得列数??
		var dataIndex = cm2.getDataIndex(i);
		// 取得列隐藏标??
		var isColumnHidden = cm2.isHidden(i);

		if (isColumnHidden) {
			// 隐藏的列不导??
		} else {
			if (dataIndex) {
				// idxs.push(dataIndex);
				headers.push(encodeURIComponent(Ext.util.Format
						.stripTags(columnHeader)))
			}
		}
	}

	// 遍历行
	for (var j = 0; j < ds.getCount(); j++) {
		var record = ds.getAt(j);
		// 遍历列
		for (var i = 0; i < cm.getColumnCount(); i++) {
			var idx = cm.getDataIndex(i);
			var header = cm.getColumnHeader(i);
			var hiddenFlag = cm.isHidden(i);
			// 打印标识
			var isPrint = cm.config[i].isPrint;
			if (hiddenFlag || isPrint == -1) {
			} else {
				if (idx) {
					var content = record.get(cm.getDataIndex(i));
					// 取得渲染函数
					var renderFunc = cm.getRenderer(i);
					// 调用渲染函数，取得渲染后的值
					var renderValue = renderFunc(content,null,record,j,i,ds);
					// 去掉列的冗余标签
					idxs.push(renderValue)
				}
			}
		}
	}

	// ==========================================================
	// 遍历行
	for (var j = 0; j < ds2.getCount(); j++) {
		var record = ds2.getAt(j);
		// 遍历列
		for (var i = 0; i < cm2.getColumnCount(); i++) {
			var idx = cm2.getDataIndex(i);
			var header = cm2.getColumnHeader(i);
			var hiddenFlag = cm2.isHidden(i);
			// 打印标识
			var isPrint = cm2.config[i].isPrint;
			if (hiddenFlag || isPrint == -1) {
			} else {
				if (idx) {
					var content = record.get(cm2.getDataIndex(i));
					// 取得渲染函数
					var renderFunc = cm2.getRenderer(i);
					// 调用渲染函数，取得渲染后的值
					var renderValue = renderFunc(content);
					// 去掉列的冗余标签
					idxs.push(renderValue)
				}
			}
		}
	}

	var url = String
			.format(
					'{0}&format=excel&start={1}&limit={2}&headers={3}&idxs={4}&excelkey={5}',
					ds.proxy.url, start || 0, limit || ds.getTotalCount(),
					headers.join(","), idxs.join(","), excelkey);
	            var opener= new Ufida.WindowOpenFun();
		        opener.windowOpen(url,null,null,"export.xls");
}

Ext.override(Ext.Toolbar.Item, {
			render : function(td) {
				this.td = td;
				td.appendChild(this.el);
				var links = this.el.getElementsByTagName("a");
				var thisItem = this;
				if (links && links.length > 0) {
					for (var i = 0, len = links.length; i < len; i++) {
						var link = links[i];
						if (link.onclick) {
							var clickTemp = link.onclick;
							link.onclick = function() {
								if (thisItem.el.disabled) {
									return;
								}
								return clickTemp();
							};
						}
					}
				}
			}
		});

		
/**
 * class Ufida.MoneyField
 * 输入金额的Field
 */

Ufida.MoneyField = function(conf){
	Ext.apply(this,conf);	
	Ufida.MoneyField.superclass.constructor.call(this,{
		maskRe : /[0123456789\.]/, // 输入数字
		maskStr: '0123456789.',
		selectOnFocus 	: true,
		allowNegative	: false,
		allowZero		: false,
		showChineseTip	: true		// 以tip形式显示汉字大写金额
	});
	Ext.apply(this,conf);	
}
Ext.extend(Ufida.MoneyField,Ext.form.TextField,{
	filterKeys : function(e){
		var k = e.getKey();
		if(!Ext.isIE && (e.isNavKeyPress() || k == e.BACKSPACE || (k == e.DELETE && e.button == -1))){
			return;
		}
		var c = e.getCharCode(), cc = String.fromCharCode(c);
		if( this.maskStr && this.maskStr.indexOf(cc)==-1){
			e.stopEvent();
		}
		if(Ext.isIE && (e.isSpecialKey() || !cc)){
			return;
		}
		if(!this.maskRe.test(cc)){
			e.stopEvent();
		}
	},
	initEvents : function(){
		Ufida.MoneyField.superclass.initEvents.call(this);		
		this.on('blur', function() {// 进行小数位的处理和字段值的验证
				var v = this.getValue();
				if( !v )return ;
				if (typeof v == 'string') {
					v = v.replace(/\.{2,}/g,".").replace(/\.$/,'');//	将连续的多个小数点合为一个,并去掉末尾小数点
					var firstDot = v.indexOf(".");
					var lastDot = v.lastIndexOf(".");
					var secondDot ;
					if (firstDot >= 0 && firstDot != lastDot) {
						var v2End = v.substring(firstDot+1,v.length);
						if( v2End ){
							secondDot = v2End.indexOf(".");
							v = v.substring(0, firstDot+secondDot+1);
						}
					}
					var num = v-0;	// parse number
					if (isNaN(num)) {
						this.markInvalid("输入不正确,请输入数字");
						return;
					}
					if( this.allowNegative === false && this.allowZero === false && num<= 0 ){
						this.markInvalid("输入不正确,请输入一个正数");
					}else if( this.allowNegative === false && this.allowZero === true && num< 0 ){
						this.markInvalid("输入不正确,请输入一个非负数");
					}
					this.setValue(v)
					return;
				}
			});
		this.on('focus',function() {
				var v = this.getValue();
				if (v) {
					this.setPlainValue(v);
				}
				if( this.selectOnFocus ){
					this.selectText();
				}
				this.clearInvalid();
			});
		this.on('keypress',function(field) {
				validate_ControlLength(field, this.maxLength||20);
			});
		// 以tip形式显示汉字大写金额
		if( this.showChineseTip === true ){
			this.el.dom.onmouseover = function() {
				var field = Ext.getCmp(this.id)
				if( this.value ){
					this.setAttribute('title',Ufida.MoneyUtil.toChinese(this.value));
				}
			};
		}
    },
    validateMoney : function(v) {
		if (typeof v == 'string') {
			v = v.replace(/[,]/g, '');
			var num = Number(v);
			if (isNaN(num)) {
				return ("输入不正确,请输入数字");
			}
			if( this.allowNegative === false && this.allowZero === false && num<= 0 ){
				return "输入不正确,请输入一个正数";
			}else if( this.allowNegative === false && this.allowZero === true && num< 0 ){
				return("输入不正确,请输入一个非负数");
			}
			return true;
		}
		return "输入格式不正确";
	},
    validateValue : function(value){
        if(value.length < 1 || value === this.emptyText){ // if it's blank
             if(this.allowBlank){
                 this.clearInvalid();
                 return true;
             }else{
                 this.markInvalid(this.blankText);
                 return false;
             }
        }
        if(value.length < this.minLength){
            this.markInvalid(String.format(this.minLengthText, this.minLength));
            return false;
        }
        if(value.length > this.maxLength){
            this.markInvalid(String.format(this.maxLengthText, this.maxLength));
            return false;
        }
        if(this.vtype){
            var vt = Ext.form.VTypes;
            if(!vt[this.vtype](value, this)){
                this.markInvalid(this.vtypeText || vt[this.vtype +'Text']);
                return false;
            }
        }
        this.validator = this.validator || this.validateMoney;
        if(typeof this.validator == "function"){
            var msg = this.validator(value);
            if(msg !== true){
                this.markInvalid(msg);
                return false;
            }
        }
        if(this.regex && !this.regex.test(value)){
            this.markInvalid(this.regexText);
            return false;
        }
        return true;
    },
    /**
     * 取得不带","的字符串
     * @return {}
     */
	getValue : function(){
		var v = Ufida.MoneyField.superclass.getValue.call(this);
		if( typeof v =='string'){
			return v.replace(/[,]/g,"");
		}
		return v ;
	},
	/**
	 * 设置金额,并自动转化为money格式
	 * @param {} v 金额数字(不带","的字符串)
	 */
	setValue : function(v){
		var moneyVal = money(v);
		if( v && v != moneyVal && !isNaN(moneyVal.replace(/[,]/g,""))){
			Ufida.MoneyField.superclass.setValue.call(this,moneyVal);
		}else{
			Ufida.MoneyField.superclass.setValue.call(this,v);
		}
	},
	setPlainValue : function(v){
		Ufida.MoneyField.superclass.setValue.call(this,v);
	},
	getPlainValue : function(v){
		return Ufida.MoneyField.superclass.getValue.call(this);
	}
});

/**
 * class BankAccountField 输入银行账号的Field
 */
Ufida.BankAccountField = function(conf) {
	conf = conf || {} ;
	Ext.applyIf(conf,{
		maskRe : /[0123456789]/, // 输入数字
		minLength : 10,
		maxLength : 32,
		msgTarget : 'under'
	});
	Ufida.BankAccountField.superclass.constructor.call(this, conf);
	Ext.apply(this, conf);
}
Ext.extend(Ufida.BankAccountField, Ext.form.TextField, {
	validateBankAccount : function(v) {
		if (typeof v == 'string') {
			var accReg = /^\d+$/;
			if (!accReg.test(v)) {
				return ("输入不正确,请输入数字");
			}
			return true;
		}
		return "输入格式不正确";
	},
	validateValue : function(value) {
		if (value.length < 1 || value === this.emptyText) { // if it's
			// blank
			if (this.allowBlank) {
				this.clearInvalid();
				return true;
			} else {
				this.markInvalid(this.blankText);
				return false;
			}
		}
		if (value.length < this.minLength) {
			this.markInvalid(String.format(this.minLengthText, this.minLength));
			return false;
		}
		if (value.length > this.maxLength) {
			this.markInvalid(String.format(this.maxLengthText, this.maxLength));
			return false;
		}
		if (this.vtype) {
			var vt = Ext.form.VTypes;
			if (!vt[this.vtype](value, this)) {
				this.markInvalid(this.vtypeText || vt[this.vtype + 'Text']);
				return false;
			}
		}
		this.validator = this.validator || this.validateBankAccount;
		if (typeof this.validator == "function") {
			var msg = this.validator(value);
			if (msg !== true) {
				this.markInvalid(msg);
				return false;
			}
		}
		if (this.regex && !this.regex.test(value)) {
			this.markInvalid(this.regexText);
			return false;
		}
		return true;
	}
});
// 订货通宝或要货通宝流程图

Ufida.FlowHelpWindow = function(config) {
	Ext.apply(this, config);
	Ufida.FlowHelpWindow.self = this;
	var self = this;
	Ext.state.Manager.setProvider(new Ext.state.CookieProvider());
	Ufida.FlowHelpWindow.superclass.constructor.call(this, {
				title : this.title,
				width : 600,
				height : 300,
				border : 'fit',
				closeAction : 'hide',
				animateTarget : 'flowhelp',
				resizable : false,
				bbar : new Ext.Toolbar({items:['->', new Ext.form.Checkbox({
					labelSeparator : '',
					boxLabel : '下次不再提示',
					checked : Ext.state.Manager.get(self.stateName) == true
							? true
							: false,
					listeners : {
						'check' : function(checkbox, checked) {
							if (checked) {
								Ext.state.Manager.set(self.stateName, true);
							} else {
								Ext.state.Manager.set(self.stateName, false);
							}
						}
					}
				}), '-', {
					xtype : 'button',
					text : '知道了',
					scale : 'medium',
					pressed : true,
					handler : function() {
						self.hide();
					}
				}]})
			});
}
Ext.extend(Ufida.FlowHelpWindow, Ext.Window, {});

Ufida.TextField = Ext.form.TextField;
/**
 * @class Ufida.BalloonBox balloon消息提示框
 * @singleton
 */
Ufida.BalloonBox = function() {
	var balloonBox;
	var timer;
	/**
	 * {0} : balloonbox 的宽度 {1} : balloonbox 的高度 {2} : 箭头离box左侧/上侧的距离 {3} :
	 * box内显示的内容
	 */
	var template_arr_bottom = new Ext.XTemplate(
			"<div class='balloon' style='width:{0}px;'>",
			"<div class='balloon-border-outter'></div>",
			"<div class='balloon-border-inner'></div>",
			"<div class='balloon-msg' style='padding-top:{1}px;padding-bottom:{1}px;'>{3}</div>",
			"<div class='balloon-border-inner'></div>",
			"<div class='balloon-border-outter'></div>",
			"<div class='balloon-arrow-bottom' align='center' style='height:4px;width:{2}px;'><div></div></div>",
			"</div>");
	var template_arr_top = new Ext.XTemplate(
			"<div class='balloon' style='width:{0}px;'>",
			"<div class='balloon-arrow-top' align='center' style='height:4px;width:{2}px;'><div></div></div>",
			"<div class='balloon-border-outter'></div>",
			"<div class='balloon-border-inner'></div>",
			"<div class='balloon-msg' style='padding-top:{1}px;padding-bottom:{1}px;'>{3}</div>",
			"<div class='balloon-border-inner'></div>",
			"<div class='balloon-border-outter'></div>", "</div>");
	var template_arr_left = new Ext.XTemplate(
			"<div class='balloon' style='width:{0}px;'>",
			"<div class='balloon-arrow-left' style='left:-3px;top:{2}px'></div>",
			"<div class='balloon-border-outter'></div>",
			"<div class='balloon-border-inner'></div>",
			"<div class='balloon-msg' style='padding-top:{1}px;padding-bottom:{1}px;'>{3}</div>",
			"<div class='balloon-border-inner'></div>",
			"<div class='balloon-border-outter'></div>", "</div>");
	var templates = {
		'top' : template_arr_top,
		'bottom' : template_arr_bottom,
		'left' : template_arr_left
	};

	return {
		/**
		 * 创建一个新的BalloonBox
		 * 
		 * @params conf: ct : balloonBox所在的父结点容器 boxHeight: 高度 boxWidth : 宽度
		 *         arrowX : 箭头距box左侧的距离 msg : box中显示的内容 arrowPos : 箭头的位置:
		 *         'left'、'bottom' 或者 'top',默认为'bottom'箭头位于box的下方
		 */
		getBalloonBox : function(conf) {
			var data = [conf.boxWidth || 100, conf.boxHeight || 10,
					conf.arrowX || 15, conf.msg || '&#160;'];
			return templates[conf.arrowPos || 'bottom'].append(conf.ct
							|| window.document, data, true);
		},
		/**
		 * 更新balloonbox中的内容
		 * 
		 * @params balloonBox
		 * @params msg 要显示的内容
		 */
		updateMsg : function(balloonBox, msg) {
			var msgEl = balloonBox.down('.balloon-msg', false);
			msgEl.update(msg || '&#160;');
		},
		/**
		 * 显示消息提示框
		 * 
		 * @params info 要显示的消息
		 * @params msgCls 消息提示框的样式
		 * @params targetEl 要与之对齐的的目标el
		 * @params align 对齐方式,默认为'tr-tr'
		 * @params arrowPos 箭头方向
		 */
		show : function(info, msgCls, targetEl, align, arrowPos, slideDir,
				isSlide) {
			var mainEl = Ext.getBody();
			arrowPos = arrowPos || 'bottom';
			var arrowX;
			switch (arrowPos) {
				case 'top' :
				case 'bottom' :
					arrowX = targetEl.getWidth() / 2;
					break;
				case 'left' :
				case 'right' :
					arrowX = 15;
					break;
			}
			info = info || '&#160;';
			if (!balloonBox) {
				balloonBox = this.getBalloonBox({
					ct : mainEl,
					boxHeight : 3,
					msg : info,
					boxWidth : targetEl.getWidth() || 180,
					arrowX : arrowX || 10,
					arrowPos : arrowPos
				});
			}
			this.updateMsg(balloonBox, info);
			balloonBox.alignTo(targetEl || Ext.get('nav'), align || 'tr-tr');// 默认对齐到页面右上角
			if (arrowPos == 'left') {
				balloonBox.setTop(balloonBox.getTop() - 8);
				balloonBox.setLeft(balloonBox.getLeft() + 5)
			}
			if (isSlide === false) {
				balloonBox.show();
				if (timer) {
					clearTimeout(timer);
				}
				// 延时隐藏
				timer = setTimeout(function() {
							balloonBox.hide();
						}, 170 * info.length + 1);
			} else {
				balloonBox.slideIn(slideDir || 't', {duration : 0.3});
				if (timer) {
					clearTimeout(timer);
				}
				// 延时隐藏
				timer = setTimeout(function() {
							balloonBox.slideOut(slideDir || 't', {duration : 0.3});
						}, 170 * info.length + 1);
			}
		},
		hide : function() {
			if (balloonBox) {
				balloonBox.hide();
			}
			if (timer) {
				clearTimeout(timer);
			}
		}
	}
}();
/**
 * 为Field增加balloon方式显示验证信息
 * 用balloon方式显示验证错误信息
 */
Ext.override(Ext.form.Field,{
	markInvalid : function(msg){
        if(!this.rendered || this.preventMark){ // not rendered
            return;
        }
        this.el.addClass(this.invalidClass);
        msg = msg || this.invalidText;
        switch(this.msgTarget){
        	 case 'balloon':
                if(this.balloonErrorEl){
                	this.balloonErrorEl.remove();
                	delete this.balloonErrorEl ;
                }
                var arrowPos = 'bottom' , arrowX , align ;
                switch( arrowPos ){
                	case 'bottom':
                	case 'top':
                		arrowX = this.el.getWidth();
                		align = 'bl-tl';
                		break ;
                	case 'left':
                		align = 'tl-tr';
                		break ;
                }
            	this.balloonErrorEl = Ufida.BalloonBox.getBalloonBox({
            		ct : Ext.getBody(),
            		boxHeight:	3,
					msg 	 : msg,
					boxWidth :170,
					arrowX 	 : arrowX,
					arrowPos : arrowPos 
            	});
                this.balloonErrorEl.setStyle('z-index',this.el.dom.parentNode.style.zIndex-0+1);
                this.balloonErrorEl.alignTo(this.el,align);
                if( arrowPos == 'left' ){
	                this.balloonErrorEl.setTop(this.balloonErrorEl.getTop()-10);
	                this.balloonErrorEl.setLeft(this.balloonErrorEl.getLeft()+5);
                }
                this.balloonErrorEl.show();
                break;
            case 'qtip':
                this.el.dom.qtip = msg;
                this.el.dom.qclass = 'x-form-invalid-tip';
                if(Ext.QuickTips){ // fix for floating editors interacting with DND
                    Ext.QuickTips.enable();
                }
                break;
            case 'title':
                this.el.dom.title = msg;
                break;
            case 'under':
                if(!this.errorEl){
                    var elp = this.getErrorCt();
                    this.errorEl = elp.createChild({cls:'x-form-invalid-msg'});
                    if(this.wrap)
                    	this.errorEl.setWidth(this.wrap.getWidth());
                    else this.errorEl.setWidth(elp.getWidth(true)-20);
                }
                this.errorEl.update(msg);
                Ext.form.Field.msgFx[this.msgFx].show(this.errorEl, this);
                break;
            case 'side':
                if(!this.errorIcon){
                    var elp = this.getErrorCt();
                    this.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});
                }
                this.alignErrorIcon();
                this.errorIcon.dom.qtip = msg;
                this.errorIcon.dom.qclass = 'x-form-invalid-tip';
                this.errorIcon.show();
                this.on('resize', this.alignErrorIcon, this);
                break;
            default:
                var t = Ext.getDom(this.msgTarget);
                t.innerHTML = msg;
                t.style.display = this.msgDisplay;
                break;
        }
        this.fireEvent('invalid', this, msg);
    },
    getErrorCt : function(){
        return this.el.findParent('.x-form-element', 5, true) || // use form element wrap if available
            this.el.findParent('.x-form-field-wrap', 5, true) ;//|| // else direct field wrap
    },
     clearInvalid : function(){
        if(!this.rendered || this.preventMark){ // not rendered
            return;
        }
        this.el.removeClass(this.invalidClass);
        switch(this.msgTarget){
        	 case 'balloon':
        	 	if( this.balloonErrorEl ){
        	 		this.balloonErrorEl.hide();
        	 		this.balloonErrorEl.remove();
        	 		delete this.balloonErrorEl ;
        	 	}
                break;
            case 'qtip':
                this.el.dom.qtip = '';
                break;
            case 'title':
                this.el.dom.title = '';
                break;
            case 'under':
                if(this.errorEl){
                    Ext.form.Field.msgFx[this.msgFx].hide(this.errorEl, this);
                }
                break;
            case 'side':
                if(this.errorIcon){
                    this.errorIcon.dom.qtip = '';
                    this.errorIcon.hide();
                    this.un('resize', this.alignErrorIcon, this);
                }
                break;
            default:
                var t = Ext.getDom(this.msgTarget);
                t.innerHTML = '';
                t.style.display = 'none';
                break;
        }
        this.fireEvent('valid', this);
    }
});

/**
 * 如果Field的allowBlank为false,自动在fieldLabel后加上红色星号"*"
 */
Ext.override(Ext.form.TextField,{
	 onRender : function(ct, position){
        Ext.form.TextField.superclass.onRender.call(this, ct, position);
	 	if(this. allowBlank === false){// 如果Field的allowBlank为false,自动在fieldLabel后加上红色星号"*"
	 		var labelText = this.getLabelText()||'';
	 		labelText = labelText.replace(/:$/,'');
	 		if( labelText !="" && !labelText.endsWith("*") ){
	 			labelText += "<span class='requireFlag' style='color:red;'>*</span>"+":";
	 			var labelEl = this.getLabelEl();
	 			if( labelEl ){
		 			labelEl.update(labelText);
	 			}
	 		}
	 	}

        this.el.addClass([this.fieldClass, this.cls]);
    },
    setAllowBlank : function( allow ){
    	if( allow === false){
    		this.allowBlank = false ;
    	}else{
    		this.allowBlank = true ;
    	}
 		var labelText = this.getLabelText() || '';
 		labelText = labelText.replace(/:$/,'');
	    if(this. allowBlank === false){
	 		if( labelText !="" && !labelText.endsWith("*") && this.getLabelEl() ){
	 			labelText += '<span class="requireFlag" style="color:red;">*</span>'+(this.labelSeparator||":");
		 		this.getLabelEl().update(labelText);
	 		}
	 	}else{
	 		if( labelText !="" && this.getLabelEl()  ){
	 			labelText = labelText.replace(/\*$/,'');
		 		this.getLabelEl().update(labelText+(this.labelSeparator||":"));
	 		}
	 	}
    }
})
/**
 * 允许对grid中的editor使用balloon方式显示验证错误信息
 */
Ext.override(Ext.Editor,{
	getValue : function(){
        var v = this.field.getValue();
        if(Ext.isDate(v)&&this.field.getFormattedStr){
        	v = this.field.getFormattedStr();
        }
        return v ;
    },
	// private
    onRender : function(ct, position){
        this.el = new Ext.Layer({
            shadow: this.shadow,
            cls: "x-editor",
            parentEl : ct,
            shim : this.shim,
            shadowOffset:4,
            id: this.id,
            constrain: this.constrain
        });
        this.el.setStyle("overflow", Ext.isGecko ? "auto" : "hidden");
        // 允许对grid中的editor使用balloon方式显示验证错误信息
        if( this.field.msgTarget != 'title' && this.field.msgTarget != 'balloon' ){
            this.field.msgTarget = 'qtip';
        }
        this.field.inEditor = true;
        this.field.render(this.el);
        if(Ext.isGecko){
            this.field.el.dom.setAttribute('autocomplete', 'off');
        }
        this.field.on("specialkey", this.onSpecialKey, this);
        if(this.swallowKeys){
            this.field.el.swallowEvent(['keydown','keypress']);
        }
        this.field.show();
        this.field.on("blur", this.onBlur, this);
        if(this.field.grow){
            this.field.on("autosize", this.el.sync,  this.el, {delay:1});
        }
    }
});


/**
 * 为String增加一些常用方法
 */
/**
 * startsWith 字符串是否以prefix开头
 * 
 * @params prefix
 */
String.prototype.startsWith = function(prefix) {
	return this.substr(0, prefix.length) == prefix;;
}
String.prototype.endsWith = function(suffix) {
	return this.substr(this.length - suffix.length) == suffix;
}
String.prototype.contains = function(cont) {
	return this.indexOf(cont) !== -1;
}
/**
 * Allows you to define a tokenized string and pass an arbitrary number of
 * arguments to replace the tokens. Each token must be unique, and must
 * increment in the format {0}, {1}
 * 
 * @example : "hello,{0}.hi,{1}".format('aaa','bbb') // -- output:
 *          "hello,aaa.hi,bbb"
 * @return {} str.format(val1,val2...)相当于String.format(str,val1,val2...);
 */
String.prototype.format = function() {
	for (var i = arguments.length; i > 0; i--) {
		arguments[i] = arguments[i - 1]; // unshift
	}
	arguments[0] = this; // the first argument is the string itself
	arguments.length++;
	return String.format.apply(this, arguments)
}
/**
 * Ext.data.Store的filter方法改为向后台发请求进行过滤
 */
Ext.override(Ext.data.Store, {
			filter : function(property, value, anyMatch, caseSensitive) {
				if (this.proxy) {// 后台请求
					this.baseParams[property] = value;
					this.load();
				} else {// 前台过滤
					var fn = this.createFilterFn(property, value, anyMatch,
							caseSensitive);
					return fn ? this.filterBy(fn) : this.clearFilter();
				}
			}
		});

/**
 * 为BasicForm.submit增加callback和exception回调方法选项
 */
Ext.override(Ext.form.Action.Submit, {
	// private
	createCallback : function(opts) {
		var opts = opts || {};
		return {
			success : this.success,
			failure : this.failure,
			callback : opts.callback, // add callback
			exception : opts.exception, // add exception
			scope : this,
			timeout : (opts.timeout * 1000)
					|| (this.form.timeout * 1000),
			upload : this.form.fileUpload ? this.success : undefined
		};
	}
})
Ext.QuickTips.init();
Ufida.checkTreeTip = function(o){
	var el = Ext.get(o);
	var parent = Ext.get(el.parent('.x-tree'))
	var text = (el.dom.innerHTML);
	var textWidth = el.getTextWidth(text);
	var textLeft = el.getLeft();
	var parentWidth = parent.getWidth();
	var parentLeft = parent.getLeft();
//	var parentClientWidth = parent.dom.offsetWidth
	parentWidth -= 10 ;// 减去器滚动条宽度
	// 当treeNode中文字超长时显示tip提示框
//	debug('textWidth+textLeft='+(textWidth+textLeft)+",parentWidth+parentLeft="+(parentWidth+parentLeft)+",parentWidth="+parentWidth+",parentLeft="+parentLeft)
	if( (textWidth+textLeft) > (parentWidth+parentLeft) ){
		if( text && text!=" " && text!="&#160;"){
			el.dom.setAttribute('ext:qtip',text );
			el.dom.qclass = 'x-ufida-inline-tip x-treenode-inline-tip x-tree-node-anchor';
			el.dom.qalign = 'tl';
//			el.dom.qmouseouthide = 'true';
		}
	}else{
		el.dom.removeAttribute('ext:qtip');
	}
}
Ufida.checkTip = function(o){
	var el = Ext.get(o);
	var parent = Ext.get(el.parent('td'))
	var text = Ext.util.Format.stripTags(el.dom.innerHTML);
	var textWidth = el.getTextWidth();
	var tdWidth = parent.getWidth();
	// 当表格中文字长度超长时显示tip提示框
	if( textWidth > tdWidth-5 ){
		if( text && text!=" " && text!="&#160;"){
			el.dom.setAttribute('ext:qtip',text );
			el.dom.qclass = 'x-ufida-inline-tip x-grid-inline-tip';
			el.dom.qalign = 'tl';
//			el.dom.qmouseouthide = 'true';
		}
	}else{
		el.dom.removeAttribute('ext:qtip');
	}
}
// 对列表的渲染修改 当某一个记录没有被渲染出来的时候，就被通过record.set修改其值 导致的渲染 bug
Ext.override(Ext.grid.GridView, {
			// private
			insertRows : function(dm, firstRow, lastRow, isUpdate) {
				if (!isUpdate && firstRow === 0 && lastRow == dm.getCount() - 1) {
					this.refresh();
				} else {
					if (!isUpdate) {
						this.fireEvent("beforerowsinserted", this, firstRow,
								lastRow);
					}
					var html = this.renderRows(firstRow, lastRow);
					var before = this.getRow(firstRow);
					if (before) {
						Ext.DomHelper.insertHtml('beforeBegin', before, html);
					} else {
						if (firstRow >= this.mainBody.dom.childNodes.length) {
							html = this.renderRows(
									this.mainBody.dom.childNodes.length,
									firstRow);
						}
						Ext.DomHelper.insertHtml('beforeEnd',
								this.mainBody.dom, html);
					}
					if (!isUpdate) {
						this.fireEvent("rowsinserted", this, firstRow, lastRow);
						this.processRows(firstRow);
					}
				}
			},
			/**
			 * 当表格中文字长度超过单元格长度时显示tip提示框
			 */
			 // private
		    doRender : function(cs, rs, ds, startRow, colCount, stripe){
		        var ts = this.templates, ct = ts.cell, rt = ts.row, last = colCount-1;
		        var tstyle = 'width:'+this.getTotalWidth()+';';
		        var buf = [], cb, c, p = {}, rp = {tstyle: tstyle}, r;
		        for(var j = 0, len = rs.length; j < len; j++){
		            r = rs[j]; cb = [];
		            var rowIndex = (j+startRow);
		            for(var i = 0; i < colCount; i++){
		                c = cs[i];
		                p.id = c.id;
		                p.css = i == 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
		                p.attr = p.cellAttr = "";
		                if( r.isEmpty === true ){// 空记录不显示任何内容
		                	p.value = ""
		                }else{
//		                	debug(c.name+"==="+HTMLEncoder.encode(r.data[c.name]))
		                	p.value = c.renderer(HTMLEncoder.encode(r.data[c.name]), p, r, rowIndex, i, ds);
		                }
		                p.attr += " onmouseover=Ufida.checkTip(this);";		// 当表格中文字长度超过单元格长度时显示tip提示框
		                p.style = c.style+";text-overflow:ellipsis; white-space:nowrap; overflow:hidden;";// 文本溢出显示省略号
		                if(p.value == undefined || p.value === "") p.value = "&#160;";
		                if(r.dirty && (r.modified && typeof r.modified[c.name] !== 'undefined')){
		                    p.css += ' x-grid3-dirty-cell';
		                }
		                cb[cb.length] = ct.apply(p);
//		                alert(c.name);//+' ---> '+cb.join(''))
		            }
		            var alt = [];
		            if(stripe && ((rowIndex+1) % 2 == 0)){
		                alt[0] = "x-grid3-row-alt";
		            }
		            if(r.dirty){
		                alt[1] = " x-grid3-dirty-row";
		            }
		            rp.cols = colCount;
		            if(this.getRowClass){
		                alt[2] = this.getRowClass(r, rowIndex, rp, ds);
		            }
		            rp.alt = alt.join(" ");
		            rp.cells = cb.join("");
		            buf[buf.length] =  rt.apply(rp);
		        }
		        return buf.join("");
		    },
		    /*
		     * inline tips -- tongliang 20091010 BEGIN
		     */
		    findRow : function(el){
		        if(!el){
		            return false;
		        }
		        return Ext.fly(el).findParent(this.rowSelector, 100);
		    },
		    findCell : function(el){
		        if(!el){
		            return false;
		        }
		        return Ext.fly(el).findParent(this.cellSelector, 100);
		    }
		    /*
		     * inline tips -- tongliang 20091010  END
		     */
		});
// 隐藏所有的Panel 后面的阴影部分，解决在查看和编辑的时候由于隐藏按钮 导致出现的shadow
Ext.override(Ext.Panel, {
			shadow : false
		});

Ext.override(Ext.PagingToolbar, {
			onLoad : function(store, r, o) {
				if (!this.rendered) {
					this.dsLoaded = [store, r, o];
					return;
				}
				this.cursor = o.params? (o.params[this.paramNames.start] || 0): 0;
				var d = this.getPageData(), ap = d.activePage, ps = d.pages;

				this.afterTextEl.el.innerHTML = String.format(this.afterPageText, d.pages);
				this.field.dom.value = ap;
				this.first.setDisabled(ap == 1);
				this.prev.setDisabled(ap == 1);
				this.next.setDisabled(ap == ps);
				this.last.setDisabled(ap == ps);
				this.loading.enable();
				this.updateInfo();
				this.fireEvent('change', this, d);
			}
		})
/**
 * 使window窗口显示时左上角不超出屏幕范围
 */
Ext.override(Ext.Window,{
	 // private
    beforeShow : function(){
        delete this.el.lastXY;
        delete this.el.lastLT;
        if(this.x === undefined || this.y === undefined){
            var xy = this.el.getAlignToXY(this.container, 'c-c');
            var pos = this.el.translatePoints(xy[0], xy[1]);
            this.x = this.x === undefined? pos.left : this.x;
            this.y = this.y === undefined? pos.top : this.y;
        }
        // 窗口左上角不超出屏幕
        if( this.x<0 ){
        	this.x =0 ;
        }
        if( this.y < 0){
        	this.y =0 ;
        }// end
        this.el.setLeftTop(this.x, this.y);

        if(this.expandOnShow){
            this.expand(false);
        }

        if(this.modal){
            Ext.getBody().addClass("x-body-masked");
            this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
            this.mask.show();
        }
    }

});
/**
 * Ext.Msg.confirm 弹出框焦点默认在"否"上,
 * Ext.MessageBox增加将焦点放到各个按钮上的方法：
 * 		focusYes,focusNo,focusOk,focusCancel
 * Ext.MessageBox增加快捷键：y:是,n:否
 */
Ext.apply(Ext.MessageBox, {
	confirm : function(title, msg, fn, scope) {
		msg = msg || '';
		msg = msg.replace(/\n/g,'<br/>');
		this.show({
			title : title,
			msg : msg,
			buttons : this.YESNO,
			fn : fn,
			scope : scope,
			icon : this.QUESTION
		});
		var dlg = Ext.MessageBox.getDialog() ;
		// 焦点默认在"否"上
		setTimeout(function(){
			dlg.buttons[2].focus();
			dlg.focusEl = dlg.buttons[2];
		}, 30);
		dlg.on('blur',function(){
			dlg.focus();
		})
		// 增加快捷键：y:是,n:否
		var self = this ;
		this.keyMap = new Ext.KeyMap( dlg.id, [{
			key : "y",
			fn : function() {
				self.quickClickButton('yes');
			}
		},{	key : "n",
			fn : function() {
				self.quickClickButton('no');
			}
		}]);
		return this;
	},
	focusYes : function(){
		this.focusButton('yes');
	},
	focusNo : function(){
		this.focusButton('no');
	},
	focusOk : function(){
		this.focusButton('ok');
	},
	focusCancel : function(){
		this.focusButton('cancel');
	},
	focusButton : function(buttonText){
		var dlg = Ext.MessageBox.getDialog();
		var buttons = dlg.buttons;
		for( var i=0, len=buttons.length ; i<len ; i++){
			if( buttons[i].text === Ext.MessageBox.buttonText[buttonText]){
				setTimeout(function(){
					buttons[i].focus();
					dlg.focusEl = buttons[i];
				},100);
				return ;
			}
		}	
	},
	quickClickButton : function(buttonText){
		var dlg = Ext.MessageBox.getDialog();
		var buttons = dlg.buttons;
		var self = this ;
		for( var i=0, len=buttons.length ; i<len ; i++){
			if( buttons[i].text === Ext.MessageBox.buttonText[buttonText]){
				buttons[i].focus();
				dlg.focusEl = buttons[i];
				if( typeof buttons[i].handler == 'function'){
					buttons[i].handler.call(self,buttonText);
				}
				return ;
			}
		}	
	}
});

/**
 * Ext.form.TriggerField增加addResetTrigger方法,
 * 可以动态地为TriggerField加上一个具有重置功能的resetTrigger
 */
Ext.override(Ext.form.TriggerField, {
	resetTriggerClass : 'x-form-clear-trigger',
	onResetTriggerClick : function(){
		this.reset();
	},
	/**
	 * 为TriggerField动态地增加一个具有重置功能的resetTrigger
	 */
	addResetTrigger : function() {
		this.trigger.remove(); // remove trigger
		
		if( !this.triggerConfig ){
			this.triggerConfig =  {
	            tag:'span', cls:'x-form-twin-triggers', cn:[
	        ]};
			this.triggerConfig.cn.push({tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.triggerClass});		        
		}
		var cn = this.triggerConfig.cn ;
		// resetTrigger
		cn.unshift({// 将resetTrigger插入到所有trigger的最前面
			tag: "img",
			src: Ext.BLANK_IMAGE_URL,
			title : '清除',
			cls: "x-form-trigger " + this.resetTriggerClass
		});
        this.trigger = this.wrap.createChild( this.triggerConfig );
        var ts = this.trigger.select('.x-form-trigger', true);
        var count = ts.getCount() ;
        var triggerField = this ;
        ts.each(function(t, all, index) {
			t.hide = function() {
				if( !triggerField.resetTrigger.isVisible() || !Ext.isIE){
					return ;
				}
				var w = triggerField.el.getWidth();
				triggerField.el.setWidth(w
						+ triggerField.resetTriggerWidth||0);
				this.dom.style.display = 'none';
				this.triggerHidden = true ;
			};
			t.show = function() {
				if( triggerField.resetTrigger.isVisible()  || !Ext.isIE){
					return ;
				}
				var w = triggerField.el.getWidth();
				this.dom.style.display = 'inline';
				triggerField.el.setWidth(w - triggerField.resetTriggerWidth||0);
				this.triggerHidden = false ;
			};
			var triggerIndex = 'Trigger' + (index);		// 由于resetTrigger在所有Trigger的最前面,所以这里不是（index＋1），而是index

			if (this['hide' + triggerIndex]) {
				t.dom.style.display = 'none';
			}
			if( index == 0 ){// 如果点击了reset trigger ,则重置field
				this.resetTrigger = t ;
				this.resetTriggerWidth = t.getWidth();
				t.on("click", this.onResetTriggerClick,this,{
						preventDefault : true
					}
				);
			}else if( count == 2){// 原Field是单trigger field（ 加上reset trigger后 trigger数为2）
				t.on("click", this['onTriggerClick'], this, {
					preventDefault : true
				});
			}else{
				 t.on("click", this['on' + triggerIndex + 'Click'], this, {
					preventDefault : true
				});
			}
			t.addClassOnOver('x-form-trigger-over');
			t.addClassOnClick('x-form-trigger-click');
		}, this);
        this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
        // 初始状态下隐藏resetTrigger
        if( this.resetTrigger ){
        	this.resetTrigger.hide();
        }
	},
	/**
	 * 给Trigger加上快捷键,按trigger的顺序使用 'Ctrl+1','Ctrl+2','Ctrl+3'作为快捷键
	 */
	initTriggerAccKey : function(){
		if( !this.trigger ){
			return ;
		}
		var ts = this.trigger.select('.x-form-trigger', true);
		var field = this;
		if( !ts ){
			return ;
		}
		ts.each(function(t,all,i){
//			var t = ts[i];
			var index = i ;
			var triggerIndex = 'Trigger' + (index-0+1);
			t.accKeyMap = new Ext.KeyMap(field.id, {
				        key	: (index-0+1),
				        shift: false,
				        ctrl : true,
				        alt : true,
				        stopEvent : true,
				        fn	: function(key,e){
//				        	debug('trigger field acckey active:'+index+":"+field['on' + triggerIndex + 'Click'])
				            field['on' + triggerIndex + 'Click'].call(field)
				        },
				        scope : field
				    });
			t.accKeyMap.stopEvent = true ;
		});
	},
	 setValue : function(v){
    	Ext.form.TriggerField.superclass.setValue.apply( this, arguments);
    	if( this.hasResetTrigger === true && this.resetTrigger ){
    		// 根据field中是否为空来决定是否显示resetTrigger ， 只有当field中非空时resetTrigger才会显示
    		if( v== undefined || v == '' || v == this.emptyText){
	    		this.resetTrigger.hide();
	    	}else{
	    		this.resetTrigger.show();    		
	    	}
    	}
    },
    initComponent : function(){
        Ext.form.TriggerField.superclass.initComponent.call(this);
         /**
         * 如果TriggerField的hasResetTrigger属性为true
         * 给TriggerField加上resetTriiger
         */
    	this.on('render',function(){
        	if( this.hasResetTrigger === true ){
        		this.addResetTrigger();
       	 	}
        	//this.initTriggerAccKey();
        });
    }

});

Ufida.TnPanel = Ext.extend(Ext.Panel, {
	baseCls : 'tnPanel',
	bodyStyle : 'padding:10px;',
	defaultColorName : "purple",// 'lightBlue',
	// collapsible :true,
	// titleCollapse: true,
	expand : function(animate) {
		if (!this.collapsed || this.el.hasFxBlock()
				|| this.fireEvent('beforeexpand', this, animate) === false) {
			return;
		}
		var doAnim = animate === true
				|| (animate !== false && this.animCollapse);
		this.el.removeClass(this.collapsedCls);
		this.beforeEffect();
		this.onExpand(doAnim, animate);
		this.tools.toggle.show(); // show tools
		return this;
	},
	onRender : function(ct, position) {
		Ext.Panel.superclass.onRender.call(this, ct, position);

		// 实现圆角样式增加四个element
		this.elements += ',outerBorder,innerBorder,outerBorderBottom,innerBorderBottom';

		this.createClasses();
		if (this.el) { // existing markup
			this.el.addClass(this.baseCls);
			this.header = this.el.down('.' + this.headerCls);
			this.bwrap = this.el.down('.' + this.bwrapCls);
			var cp = this.bwrap ? this.bwrap : this.el;
			this.tbar = cp.down('.' + this.tbarCls);
			this.body = cp.down('.' + this.bodyCls);
			this.bbar = cp.down('.' + this.bbarCls);
			this.footer = cp.down('.' + this.footerCls);
			this.fromMarkup = true;
		} else {
			this.el = ct.createChild({
						id : this.id,
						cls : this.baseCls
					}, position);
		}
		var el = this.el, d = el.dom;

		if (this.cls) {
			this.el.addClass(this.cls);
		}

		if (this.buttons) {
			this.elements += ',footer';
		}
		// This block allows for maximum flexibility and performance
		// when using existing markup
		// framing requires special markup
		if (this.frame) {
			el.insertHtml('afterBegin', String.format(Ext.Element.boxMarkup,
							this.baseCls));

			this.createElement('outerBorder',
					d.firstChild.firstChild.firstChild);
			this.createElement('innerBorder', d);
			this.createElement('header', d);
			this.createElement('bwrap', d);

			// append the mid and bottom frame to the bwrap
			var bw = this.bwrap.dom;
			var b1 = ml = d.childNodes[1], bl = d.childNodes[2];
			bw.appendChild(ml);
			bw.appendChild(bl);

			var mc = bw.firstChild.firstChild.firstChild;
			this.createElement('tbar', mc);
			this.createElement('body', mc);
			this.createElement('bbar', mc);
			this.createElement('footer', bw.lastChild.firstChild.firstChild);

			this.createElement('innerBorderBottom', d);
			this.createElement('outerBorderBottom', d);
			if (!this.footer) {
				this.bwrap.dom.lastChild.className += ' x-panel-nofooter';
			}
		} else {
			this.createElement('outerBorder', d);
			this.createElement('innerBorder', d);
			this.createElement('header', d);
			this.createElement('bwrap', d);

			// append the mid and bottom frame to the bwrap
			var bw = this.bwrap.dom;
			this.createElement('tbar', bw);
			this.createElement('body', bw);
			this.createElement('bbar', bw);
			this.createElement('footer', bw);

			this.createElement('innerBorderBottom', d);
			this.createElement('outerBorderBottom', d);

			if (!this.header) {
				this.body.addClass(this.bodyCls + '-noheader');
				if (this.tbar) {
					this.tbar.addClass(this.tbarCls + '-noheader');
				}
			}
		}

		if (this.border === false) {
			this.el.addClass(this.baseCls + '-noborder');
			this.body.addClass(this.bodyCls + '-noborder');
			if (this.header) {
				this.header.addClass(this.headerCls + '-noborder');
			}
			if (this.footer) {
				this.footer.addClass(this.footerCls + '-noborder');
			}
			if (this.tbar) {
				this.tbar.addClass(this.tbarCls + '-noborder');
			}
			if (this.bbar) {
				this.bbar.addClass(this.bbarCls + '-noborder');
			}
		}

		if (this.bodyBorder === false) {
			this.body.addClass(this.bodyCls + '-noborder');
		}

		if (this.bodyStyle) {
			this.body.applyStyles(this.bodyStyle);
		}

		this.bwrap.enableDisplayMode('block');

		if (this.header) {
			// this.header.unselectable();

			// for tools, we need to wrap any existing header markup
			if (this.headerAsText) {
				this.header.dom.innerHTML = '<span class="'
						+ this.headerTextCls + '">' + this.header.dom.innerHTML
						+ '</span>';

				if (this.iconCls) {
					this.setIconClass(this.iconCls);
				}
			}
		}

		if (this.floating) {
			this.makeFloating(this.floating);
		}

		if (this.collapsible) {
			this.tools = this.tools ? this.tools.slice(0) : [];
			if (!this.hideCollapseTool) {
				this.tools[this.collapseFirst ? 'unshift' : 'push']({
					id : 'toggle',
					handler : this.toggleCollapse,
					scope : this
				});
			}
			if (this.titleCollapse && this.header) {
				this.header.on('click', this.toggleCollapse, this);
				this.header.setStyle('cursor', 'pointer');
			}
		}
		if (this.tools) {
			var ts = this.tools;
			this.tools = {};
			this.addTool.apply(this, ts);
		} else {
			this.tools = {};
		}

		if (this.buttons && this.buttons.length > 0) {
			// tables are required to maintain order and for correct
			// IE layout
			var tb = this.footer.createChild({
				cls : 'x-panel-btns-ct',
				cn : {
					cls : "x-panel-btns x-panel-btns-" + this.buttonAlign,
					html : '<table cellspacing="0"><tbody><tr></tr></tbody></table><div class="x-clear"></div>'
				}
			}, null, true);
			var tr = tb.getElementsByTagName('tr')[0];
			for (var i = 0, len = this.buttons.length; i < len; i++) {
				var b = this.buttons[i];
				var td = document.createElement('td');
				td.className = 'x-panel-btn-td';
				b.render(tr.appendChild(td));
			}
		}

		if (this.tbar && this.topToolbar) {
			if (Ext.isArray(this.topToolbar)) {
				this.topToolbar = new Ext.Toolbar(this.topToolbar);
			}
			this.topToolbar.render(this.tbar);
			this.topToolbar.ownerCt = this;
		}
		if (this.bbar && this.bottomToolbar) {
			if (Ext.isArray(this.bottomToolbar)) {
				this.bottomToolbar = new Ext.Toolbar(this.bottomToolbar);
			}
			this.bottomToolbar.render(this.bbar);
			this.bottomToolbar.ownerCt = this;
		}

		// 自动设置Panel高度
		if (this.body && this.autoHeight && this.minBodyHeight) {
			this.body.setStyle({
				'min-height' : this.minBodyHeight + this.body.defaultUnit,
				'height' : this.minBodyHeight + this.body.defaultUnit
			});
		}

		if (this.header) {
			this.header
					.addClass(this.headerIconCls || 'tnPanel-default-header');
		}
		// 设置面板样式
		this.setPanelStyle(this.colorName || this.defaultColorName);

	},
	setPanelStyle : function(colorName) {
		if (!colorName in Ufida.TnPanel.colors) {
			return;
		}
		var borderColor = Ufida.TnPanel.colors[colorName].borderColor
				|| "#9BC9DF";
		var groundColor = Ufida.TnPanel.colors[colorName].groundColor
				|| "#DBEDF5";
		var contentGroundColor = Ufida.TnPanel.colors[colorName].contentGroundColor
				|| "#fff";

		// set styles
		if (this.innerBorder) {
			this.innerBorder.setStyle({
				'background-color' : groundColor,
				'border-left' : '1px solid ' + borderColor,
				'border-right' : '1px solid ' + borderColor
			});
		}
		if (this.outerBorder) {
			this.outerBorder.setStyle({
				'background' : borderColor
			});
		}
		if (this.innerBorderBottom) {
			this.innerBorderBottom.setStyle({
				'background-color' : groundColor,
				'border-left' : '1px solid ' + borderColor,
				'border-right' : '1px solid ' + borderColor
			});
		}
		if (this.outerBorderBottom) {
			this.outerBorderBottom.setStyle({
				'background' : borderColor
			});
		}
		if (this.header) {
			this.header.setStyle({
				'background-color' : groundColor,
				'border-left' : '1px solid ' + borderColor,
				'border-right' : '1px solid ' + borderColor
			});
		}
		if (this.bwrap) {
			this.bwrap.setStyle({
				'background-color' : groundColor,
				'border-left' : '1px solid ' + borderColor,
				'border-right' : '1px solid ' + borderColor
			});
		}
		if (this.body) {
			this.body.setStyle({
				'background-color' : contentGroundColor,
				'border' : '3px solid ' + groundColor,
				'border-top' : '3px solid ' + groundColor
			});
		}
	},
	// private
	createClasses : function() {
		this.innerBorderCls = this.baseCls + '-border-inner';
		this.outerBorderCls = this.baseCls + '-border-outer';
		this.innerBorderBottomCls = this.baseCls + '-border-inner';
		this.outerBorderBottomCls = this.baseCls + '-border-outer';

		this.headerCls = this.baseCls + '-header';
		this.headerIconCls = this.baseCls + "-" + this.headerIconCls
				+ '-header';
		this.headerTextCls = this.baseCls + '-header-text';
		this.bwrapCls = this.baseCls + '-bwrap';
		this.tbarCls = this.baseCls + '-tbar';
		this.bodyCls = this.baseCls + '-body';
		this.bbarCls = this.baseCls + '-bbar';
		this.footerCls = this.baseCls + '-footer';
	},
	onResize : function(w, h) {
		if (w !== undefined || h !== undefined) {
			if (!this.collapsed) {
				/**
				 * 改变Panel尺寸时调整Panel的大小
				 */
				if (typeof w == 'number') {
					this.body.setWidth(this.adjustBodyWidth(w
							- this.getFrameWidth())
							- 3);// -3
				} else if (w == 'auto') {
					this.body.setWidth(w);//
				}
				if (typeof h == 'number') {
					this.body.setHeight(this.adjustBodyHeight(h
							- this.getFrameHeight())
							- 4);// -4
				} else if (h == 'auto') {
					this.body.setHeight(h); //
				}
			} else {
				this.queuedBodySize = {
					width : w,
					height : h
				};
				if (!this.queuedExpand && this.allowQueuedExpand !== false) {
					this.queuedExpand = true;
					this.on('expand', function() {
								delete this.queuedExpand;
								this.onResize(this.queuedBodySize.width,
										this.queuedBodySize.height);
								this.doLayout();
							}, this, {
								single : true
							});
				}
			}
			this.fireEvent('bodyresize', this, w, h);
		}
		this.syncShadow();
	}
});

/**
 * Ufida.TnPanel的颜色样式常量
 * 
 * @type {}
 */
Ufida.TnPanel.colors = {
	lightBlue : {
		groundColor : "#DBEDF5", // Panel背景色
		borderColor : "#9BC9DF", // 外边框颜色
		contentGroundColor : "#fff" // Panel内容区域背景色,默认为白色
	},
	lightGreen : {
		groundColor : "#DBF1D4",
		borderColor : "#A5DA94"
	},
	lightOrange : {
		groundColor : "#F2EAB7",
		borderColor : "#E3D686"
	},
	strawYellow : {
		groundColor : "#FDE7A2",
		borderColor : "#FCD372",
		contentGroundColor : "#F0F7F9" // Panel内容区域背景色
	},
	lightPurple : {
		groundColor : "#D8DFEC",
		borderColor : "#A8BEE7"
	},
	pink : {
		groundColor : "#FED6D2",
		borderColor : "#E5ADA7"
	},
	green : {
		groundColor : "#CAEF85",
		borderColor : "#A0E225",
		contentGroundColor : "#F0F7F9" // Panel内容区域背景色
	},
	purple : {
		groundColor : "#E7D0FF",
		borderColor : "#D9B3FF"
	},
	lightCyan : {
		// groundColor : "#D2E6D2",
		borderColor : "#BEE7DA"
	},
	gray : {
		groundColor : "#555",
		// groundColor : "#404040",
		borderColor : "#B2B2B2",
		contentGroundColor : "#D4D0C8" // Panel内容区域背景色
	}
};

// el mask 增加加载时的动态图标
Ext.override(Ext.Element, {
			mask : function(msg, msgCls) {
				if (this.getStyle("position") == "static") {
					this.setStyle("position", "relative");
				}
				if (this._maskMsg) {
					this._maskMsg.remove();
				}
				if (this._mask) {
					this._mask.remove();
				}
				this._mask = Ext.DomHelper.append(this.dom, {
							cls : "ext-el-mask"
						}, true);

				this.addClass("x-masked");
				this._mask.setDisplayed(true);
				if (typeof msg == 'string') {
					this._maskMsg = Ext.DomHelper.append(this.dom, {
								cls : "ext-el-mask-msg",
								cn : {
									tag : 'div'
								}
							}, true);
					var mm = this._maskMsg;
					mm.dom.className = msgCls
							? "ext-el-mask-msg " + msgCls
							: "ext-el-mask-msg" + " x-mask-loading";// add
																	// loading
																	// mask
					// icon
					mm.dom.firstChild.innerHTML = msg;
					mm.setDisplayed(true);
					mm.center(this);
				}
				if (Ext.isIE && !(Ext.isIE7 && Ext.isStrict)
						&& this.getStyle('height') == 'auto') { // ie will not
																// expand full
					// height automatically
					this._mask.setSize(this.dom.clientWidth, this.getHeight());
				}
				return this._mask;
			}
		});

/**
 * 全文搜索页面的翻页工具栏
 * @class Ufida.TnPagingToolbar
 * @extends Ext.PagingToolbar
 */
Ufida.TnPagingToolbar = Ext.extend(Ext.PagingToolbar, {
	prevText : '上一页',
	initComponent : function() {
		this.addEvents('change', 'beforechange');
		Ufida.TnPagingToolbar.superclass.initComponent.call(this);
		this.cursor = 0;
		this.bind(this.store);

		this.pageLinkTpl = new Ext.XTemplate(
				'<td><a href="javascript:void(0)" class="x-tnPagingToolbar-pagelink" pageNo={pageNo}>{text}',
				'</a></td>');
	},
	autoCreate : {
		cls : 'x-tnPagingToolbar',
		html : '<table cellspacing="1" class="x-tnPagingToolbar-content"><tr id="x-tnToolbar-contentCt"></tr></table>'
	},

	// private
	onRender : function(ct, position) {
		Ufida.TnPagingToolbar.superclass.onRender.call(this, ct, position);
		if (this.dsLoaded) {
			this.onLoad.apply(this, this.dsLoaded);
		}
		this.contentCt = this.el.down('#x-tnToolbar-contentCt');
	},
	renderBody : function() {
		// 清除原有的body内容
		var tds = this.contentCt.query('td');
		for (var i = 0, len = tds.length; i < len; i++) {
			Ext.get(tds[i]).remove();
		}
		var totalCount = this.store.getTotalCount();
		if (totalCount == 0) {// 没有记录时显示空信息
			return Ext.DomHelper.insertHtml("beforeEnd", this.contentCt.dom,
					"<td>" + this.emptyMsg + "</td>");
		}
		var pageSize = this.pageSize;
		var cursor = this.cursor;
		var curPageNo = parseInt(cursor / pageSize + 1);
		var totalPageCount = parseInt(totalCount % pageSize != 0 ? totalCount
				/ pageSize + 1 : totalCount / pageSize);
		// 上一页
		if (curPageNo != 1) {
			this.addPageLink(curPageNo - 1, this.prevText,
					"x-tnPagingToolbar-prevPage");
		}
		var startNo = curPageNo - 5;
		var endNo = curPageNo + 5;
		if (startNo < 1) {
			startNo = 1;
		}
		if (endNo > totalPageCount) {
			endNo = totalPageCount;
		}
		// 第一页
		if (startNo != 1) {
			this.addPageLink(1, 1 + "...");
		}
		// 生成每页链接
		for (var i = startNo, len = endNo; i <= len; i++) {
			var link = this.addPageLink(i, i);
			if (i == curPageNo) {
				link.addClass("x-tnPagingToolbar-pagelink-selected");
			}
		}
		// 最后页
		if (endNo != totalPageCount) {
			this.addPageLink(totalPageCount, "..." + totalPageCount);
		}
		// 下一页
		if (curPageNo != totalPageCount) {
			this.addPageLink(curPageNo + 1, this.nextText,
					"x-tnPagingToolbar-nextPage");
		}
	},
	/**
	 * 生成一个页面链接按钮,点击可以转到相应页面
	 * @param {}  pageNo 点击转到的页面号
	 * @param {}  text 链接中显示的文字
	 * @param {}  cls 链接按钮的cls
	 * @return {}
	 */
	addPageLink : function(pageNo, text, cls) {
		var self = this;
		var html = this.pageLinkTpl.apply({
			pageNo : pageNo,
			text : text
		});
		var link = Ext.get(Ext.DomHelper.insertHtml("beforeEnd",this.contentCt.dom, html)).down("a");
		link.on('click', function(link) {
					var pageNo = (Ext.getDom(this).getAttribute("pageNo") || 0)- 0;
					self.doLoad((pageNo - 1) * self.pageSize);
				});
		if (cls) {
			link.addClass(cls);
		}
		return link;
	},
	// private
	onLoad : function(store, r, o) {
		if (!this.rendered) {
			this.dsLoaded = [store, r, o];
			return;
		}
		this.cursor = o.params ? o.params[this.paramNames.start] : 0;
		this.fireEvent('change', this, this.getPageData());
		this.renderBody();
	}
});

/* 重写DateField */
//Ext.form.DateField = Ext.extend(Ext.form.TriggerField, {
//	format : "m/d/Y",
//	altFormats : "m/d/Y|n/j/Y|n/j/y|m/j/y|n/d/y|m/j/Y|n/d/Y|m-d-y|m-d-Y|m/d|m-d|md|mdy|mdY|d|Y-m-d",
//	disabledDaysText : "Disabled",
//	disabledDatesText : "Disabled",
//	minText : "The date in this field must be equal to or after {0}",
//	maxText : "The date in this field must be equal to or before {0}",
//	invalidText : "{0} is not a valid date - it must be in the format {1}",
//	triggerClass : 'x-form-date-trigger',
//	showToday : true,
//	// private
//	defaultAutoCreate : {
//		tag : "input",
//		type : "text",
//		size : "10",
//		autocomplete : "off"
//	},
//
//	initComponent : function() {
//		Ext.form.DateField.superclass.initComponent.call(this);
//		this.addEvents('select');
//		if (typeof this.minValue == "string") {
//			this.minValue = this.parseDate(this.minValue);
//		}
//		if (typeof this.maxValue == "string") {
//			this.maxValue = this.parseDate(this.maxValue);
//		}
//		this.disabledDatesRE = null;
//		this.initDisabledDays();
//	},
//	// private
//	initDisabledDays : function() {
//		if (this.disabledDates) {
//			var dd = this.disabledDates;
//			var re = "(?:";
//			for (var i = 0; i < dd.length; i++) {
//				re += dd[i];
//				if (i != dd.length - 1)
//					re += "|";
//			}
//			this.disabledDatesRE = new RegExp(re + ")");
//		}
//	},
//
//	setDisabledDates : function(dd) {
//		this.disabledDates = dd;
//		this.initDisabledDays();
//		if (this.menu) {
//			this.menu.picker.setDisabledDates(this.disabledDatesRE);
//		}
//	},
//
//	setDisabledDays : function(dd) {
//		this.disabledDays = dd;
//		if (this.menu) {
//			this.menu.picker.setDisabledDays(dd);
//		}
//	},
//
//	setMinValue : function(dt) {
//		this.minValue = (typeof dt == "string" ? this.parseDate(dt) : dt);
//		if (this.menu) {
//			this.menu.picker.setMinDate(this.minValue);
//		}
//	},
//
//	setMaxValue : function(dt) {
//		this.maxValue = (typeof dt == "string" ? this.parseDate(dt) : dt);
//		if (this.menu) {
//			this.menu.picker.setMaxDate(this.maxValue);
//		}
//	},
//
//	// private
//	validateValue : function(value) {
//		value = this.formatDate(value);
//		if (!Ext.form.DateField.superclass.validateValue.call(this, value)) {
//			return false;
//		}
//		if (value.length < 1) { // if it's blank and textfield
//			// didn't flag it then it's
//			// valid
//			return true;
//		}
//		var svalue = value;
//		value = this.parseDate(value);
//		if (!value) {
//			this.markInvalid(String.format(this.invalidText, svalue,
//					this.format));
//			return false;
//		}
//		var time = value.getTime();
//		if (this.minValue && time < this.minValue.getTime()) {
//			this.markInvalid(String.format(this.minText, this
//							.formatDate(this.minValue)));
//			return false;
//		}
//		if (this.maxValue && time > this.maxValue.getTime()) {
//			this.markInvalid(String.format(this.maxText, this
//							.formatDate(this.maxValue)));
//			return false;
//		}
//		if (this.disabledDays) {
//			var day = value.getDay();
//			for (var i = 0; i < this.disabledDays.length; i++) {
//				if (day === this.disabledDays[i]) {
//					this.markInvalid(this.disabledDaysText);
//					return false;
//				}
//			}
//		}
//		var fvalue = this.formatDate(value);
//		if (this.disabledDatesRE && this.disabledDatesRE.test(fvalue)) {
//			this.markInvalid(String.format(this.disabledDatesText, fvalue));
//			return false;
//		}
//		return true;
//	},
//
//	// private
//	// Provides logic to override the default
//	// TriggerField.validateBlur which just returns true
//	validateBlur : function() {
//		return !this.menu || !this.menu.isVisible();
//	},
//
//	getValue : function() {
//		return this
//				.parseDate(Ext.form.DateField.superclass.getValue.call(this))
//				|| "";
//	},
//
//	setValue : function(date) {
//		Ext.form.DateField.superclass.setValue.call(this, this.formatDate(this
//						.parseDate(date)));
//	},
//
//	// private
//	parseDate : function(value) {
//		if (!value || Ext.isDate(value)) {
//			return value;
//		}
//		var v = Date.parseDate(value, this.format);
//		if (!v && this.altFormats) {
//			if (!this.altFormatsArray) {
//				this.altFormatsArray = this.altFormats.split("|");
//			}
//			for (var i = 0, len = this.altFormatsArray.length; i < len && !v; i++) {
//				v = Date.parseDate(value, this.altFormatsArray[i]);
//			}
//		}
//		return v;
//	},
//
//	// private
//	onDestroy : function() {
//		if (this.menu) {
//			this.menu.destroy();
//		}
//		if (this.wrap) {
//			this.wrap.remove();
//		}
//		Ext.form.DateField.superclass.onDestroy.call(this);
//	},
//
//	// private
//	formatDate : function(date) {
//		return Ext.isDate(date) ? date.dateFormat(this.format) : date;
//	},
//
//	// private
//	menuListeners : {
//		select : function(m, d) {
//			this.setValue(d);
//			this.fireEvent('select', this, d);
//		},
//		show : function() { // retain focus styling
//			this.onFocus();
//		},
//		hide : function() {
//			this.focus.defer(10, this);
//			var ml = this.menuListeners;
//			this.menu.un("select", ml.select, this);
//			this.menu.un("show", ml.show, this);
//			this.menu.un("hide", ml.hide, this);
//		}
//	},
//
//	// private
//	// Implements the default empty TriggerField.onTriggerClick
//	// function to display the DatePicker
//	onTriggerClick : function() {
//		if (this.disabled) {
//			return;
//		}
//		if (this.menu == null) {
//			this.menu = new Ext.menu.DateMenu();
//		}
//		Ext.apply(this.menu.picker, {
//					minDate : this.minValue,
//					maxDate : this.maxValue,
//					disabledDatesRE : this.disabledDatesRE,
//					disabledDatesText : this.disabledDatesText,
//					disabledDays : this.disabledDays,
//					disabledDaysText : this.disabledDaysText,
//					format : this.format,
//					showToday : this.showToday,
//					minText : String.format(this.minText, this
//									.formatDate(this.minValue)),
//					maxText : String.format(this.maxText, this
//									.formatDate(this.maxValue))
//				});
//		this.menu.on(Ext.apply({}, this.menuListeners, {
//					scope : this
//				}));
//		this.menu.picker.setValue(this.getValue() || new Date());
//		this.menu.show(this.el, "tl-bl?");
//	},
//
//	// private
//	beforeBlur : function() {
//		var v = this.parseDate(this.getRawValue());
//		if (v) {
//			this.setValue(v);
//		}
//	}
//
//});
//Ext.reg('datefield', Ext.form.DateField);

/**
 * *******************************************************************************
 * 进销存单据打印 Begin
 * *******************************************************************************
 */
Ext.override(Ext.form.DateField, {
			getFormattedStr : function() {
				return this.formatDate(this.getValue());
			}
		});

Ufida.BillListPrinter = function(conf) {
	Ext.apply(this, conf);
	Ufida.BillListPrinter.superclass.constructor.call(this, {});
	Ext.apply(this, conf);
}
Ext.extend(Ufida.BillListPrinter, Ext.util.Observable, {
	initTpl : function(printSetter, records) {
		var docArray = [
				'<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">',
				'<html>',
				'<head>',
				'<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">',
				'<script type="text/javascript" src="/loginAction.do?method=defaultJsp"></script>',
				'<script type="text/javascript" src="/extjs/adapter/ext/ext-base.js"></script>',
				'<script type="text/javascript" src="/extjs/ext-all.js"></script>',
				'<script type="text/javascript" src="/ufida/ufida.js"></script>',
				'<script type="text/javascript" src="/js/util.js"></script>',
				'<script type="text/javascript" src="/scmMng/js/util.js"></script>',
				'<script type="text/javascript" src="/scmMng/js/printTPL.js"></script>',
				'<script type="text/javascript" src="/scmMng/js/print.js"></script>',
				'<link rel="stylesheet" type="text/css" href="/extjs/resources/css/ext-all.css" />',
				'<link rel="stylesheet" media="screen" type="text/css" href="/js/print/screen.css"/>',
				'<link rel="stylesheet" media="print" type="text/css" href="/js/print/print.css"/>',
				'<style media="print">.noprint{display:none;}</style>',
				'<style type="text/css">',
				'body,html{margin:0px auto; padding:0;text-align:center}',
				'div,table{margin:0px auto;}',
				'.x-print-bill-title{color:#333333; text-align:center; font-size:2em; font-weight:bold; padding:10px 0 5px 0; border-bottom:1px solid #999999;}',
				'.container{font-size:12px; margin:5px auto 5px auto;}',
				'.container td{padding:4px 2px; text-align:left;}',
				'.container td.billFormLabel{width:16%;white-space:nowrap;text-align:left;}',
				'.billFormField{width:33%;white-space:nowrap;}',
				'.billFormLabelNarrow{width:5%;white-space:nowrap;}',
				'.list{border:1px solid #000000; border-collapse:collapse; font-size:12px;}',
				'.list th{border:1px solid #000000; border-collapse:collapse; padding:4px 2px; background:#EDEDED}',
				'.list td{border:1px solid #000000; border-collapse:collapse; padding:4px 2px;}',
				'.list .sum{background:#F9F9F9; font-weight:bold;}',
				'.list .number{text-align:right;}',
				'.print-body-bill{width:95%;margin:0px auto;}',
				'.border1{border:0px solid red !important;}',
				'.print-pagebreak-flag{page-break-after: always;}',
				'.print-pagebreak-icon{height:10px;background:#fff url("/images/page-break.gif") 50% 0 no-repeat;}',
				'.x-print-pager{height:20px;background:#F3F6FF;cursor:pointer;}',
				'.x-print-pager-text{float:right; color:blue ;font-size:smaller;margin-top:5px;}',
				'.x-print-pager-over{height:20px;background:#CFD5E4;}',
				'.x-print-pager-on{page-break-after: always;background: #F3F6FF url("/images/page_break.gif") 50% 0 no-repeat;}',
				'#ufidaPrintSetting{margin:10px;}', '</style>'];
				
			if (Ext.isIE) {
			docArray.push('<script type="text/javascript">' +
							'function doPrint(how) {' +
								'var myDoc = { ' +
//								    'fitToPage:true,'+
								 	'autoBreakPage:true,'+
									'autoBreakTable:{id:"mytable"},'+	
									
									'header  : {height:20,html:"<div style=text-align:right;width:100%;>第 #p 页/共 #P 页</div>"}, '+
									'documents:document, ' +
									'copyrights : "杰创软件拥有版权 www.jatools.com"  ' +
								'}; ' +
								'if (how == "preview"){ ' +
									'jatoolsPrinter.printPreview(myDoc); ' +
								'} else{ ' +
									'jatoolsPrinter.print(myDoc, false); } ' +
							'}' +
							'</script> ');
			}else{
			}
			docArray.push('</head><body>');
			
		if (Ext.isIE) {
			// 打印样式表
			docArray.push(
							'<DIV class="noprint" align=center>',
							'<OBJECT height=0 width=0 ID="jatoolsPrinter" CLASSID="CLSID:B43D3361-D975-4BE2-87FE-057188254255" codebase="/jatoolsPrinter.cab#version=4,2,0,0"></OBJECT>',
							'<INPUT onclick=javascript:doPrint() type=button value=打印 name=button_print />&nbsp;&nbsp;',
							'<INPUT onclick=javascript:doPrint("preview") type=button value=打印预览 name=button_show />&nbsp;&nbsp;',
							'<INPUT onclick=javascript:setTpl() type=button value=打印模板设置 name=button_show />&nbsp;&nbsp;',
							'<div id="ufidaPrintSetting"></div>', '</DIV>');
		} else {
			docArray.push(
							'<DIV class="noprint print-setting-panel" align=center>',
							'<INPUT onclick=javascript:window.print(); type=button value=打印 name=button_print />&nbsp;&nbsp;',
							'<INPUT onclick=javascript:setTpl() type=button value=打印模板设置 name=button_show />&nbsp;&nbsp;',
							'请点击浏览器“文件”菜单，选择“页面设置”和“打印预览”功能',
							'</DIV>');
		}
		
		docArray.push('<div id="page1"><table id="mytable">{body}</table></div>', '</body></html>');
		this.documentTpl = new Ext.XTemplate(docArray.join(''));
		var div1 = '';
		if(printSetter.cLogo){
			if(printSetter.cLogo.isShow){
				div1 = '<div align="left">'+printSetter.cLogo.itemName+'<img src="http://uop.wecoo.com/'+logo+'" height="100" width="80" ></img></div>';
			}else{
			}
		}else{
		}
		
		var div2 = '';
		if(printSetter.cName){
			if(printSetter.cName.isShow){
				div2 = '<div align="left">'+printSetter.cName.itemName+AN+'</div>';
			}else{
			}
		}else{
		}
		
		this.bodyTpl = new Ext.XTemplate(
				'<tr><td>',
				'<div class="print-body-bill" title={toolTip}>',
				''+div1+'',
				''+div2+'',
				'<div class="x-print-bill-title">{title}</div>',
				'<div class="x-print-form">{form}</div>',
				'<div class="x-print-form">{custom}</div>',
				'<div class="x-print-details" style="border: 2px solid #000000;">{details}</div>',
				'<div class="x-print-footer">{footer}</div>',
				'</div>',
				'</td></tr>');

		var formArr = [];
		var customArr = [];
		var listArr = [];
		var bottomArr = [];

		for (var ele in printSetter) {
			if (printSetter[ele].itemType == 'F' && printSetter[ele].isShow) {
				formArr.push(printSetter[ele])
			} else if (printSetter[ele].itemType == 'L'
					&& printSetter[ele].isShow) {
				listArr.push(printSetter[ele])
			} else if (printSetter[ele].itemType == 'B'
					&& printSetter[ele].isShow) {
				bottomArr.push(printSetter[ele])
			} else if (printSetter[ele].itemType == 'C'
					&& printSetter[ele].isShow
					&& (records[0].data.templateDto[printSetter[ele].itemKey] !== '' && records[0].data.templateDto[printSetter[ele].itemKey] !== undefined)) {
				customArr.push(printSetter[ele])
			}
		}
		var lineNum = 0;
		// 商
		var quotient = formArr.length / 2;
		lineNum = Math.ceil(quotient);
		// 余数
		var mod = formArr.length % 2;

		var arr = [];
		arr.push('<table width="80%" border="0" cellspacing="0" cellpadding="0" class="container">');

		for (var i = 0, length = lineNum; i < length; i++) {
			arr.push("<tr>");
			if (i == lineNum - 1 && mod != 0) {
				
				arr.push('<td class="billFormLabel">' + formArr[2 * i].itemName + '</td><td class="billFormField">{'
						+ formArr[2 * i].itemCode + '}</td>');
			} else {
				if(formArr[2 * i].itemName=='公司Logo：')
				  continue;
				arr.push('<td class="billFormLabel">' + formArr[2 * i].itemName + '</td><td class="billFormField">{'
								+ formArr[2 * i].itemCode + '}</td>', '<td class="billFormLabel">'
								+ formArr[2 * i + 1].itemName + '</td><td class="billFormField">{'
								+ formArr[2 * i + 1].itemCode + '}</td>');
			}
			arr.push("</tr>");
		}
		arr.push('</table>');

		this.formTpl = new Ext.XTemplate(arr);

		lineNum = 0;
		// 商
		quotient = customArr.length / 2;
		lineNum = Math.ceil(quotient);
		// 余数
		mod = customArr.length % 2;
		arr = [];
		arr.push('<table width="80%" border="0" cellspacing="0" cellpadding="0" class="container">');

		for (var i = 0, length = lineNum; i < length; i++) {
			arr.push("<tr>");
			if (i == lineNum - 1 && mod != 0) {
				if (customArr[2 * i].customName) {
					arr.push('<td class="billFormLabel">' + customArr[2 * i].itemName + '</td><td class="billFormField">{'
							+ customArr[2 * i].itemCode + '}</td>');
				} else {
					arr.push('<td class="billFormLabel">{' + customArr[2 * i].itemName
							+ '}：</td><td class="billFormField">{' + customArr[2 * i].itemCode
							+ '}</td>');
				}

			} else {
				if (customArr[2 * i].customName) {
					arr.push('<td class="billFormLabel">' + customArr[2 * i].itemName + '</td><td class="billFormField">{'
									+ customArr[2 * i].itemCode + '}</td>',
							'<td class="billFormLabel">' + customArr[2 * i + 1].itemName
									+ '</td><td class="billFormField">{'
									+ customArr[2 * i + 1].itemCode + '}</td>');
				} else {
					arr.push('<td class="billFormLabel">{' + customArr[2 * i].itemName
									+ '}：</td><td class="billFormField">{'
									+ customArr[2 * i].itemCode + '}</td>',
							'<td class="billFormLabel">{' + customArr[2 * i + 1].itemName
									+ '}：</td><td class="billFormField">{'
									+ customArr[2 * i + 1].itemCode + '}</td>');
				}

			}
			arr.push("</tr>");
		}
		arr.push('</table>');
		this.custTpl = new Ext.XTemplate(arr);

		arr = [];
		arr.push('<table width="100%" border="0" cellspacing="0" cellpadding="0" class="list"><tr>')

		for (var i = 0, length = listArr.length; i < length; i++) {
			arr.push("<th>");
			arr.push(listArr[i].itemName);
			arr.push("</th>");
		}
		arr.push('</tr>');
		arr.push('{detailsRows}')
		arr.push('<tr>');
		for (var i = 0, length = listArr.length; i < length; i++) {
			arr.push("<td>");
			if (i == 0) {
				arr.push('合计：');
			}
			arr.push('{' + listArr[i].itemCode + '}');
			arr.push("</td>");
		}
		arr.push('</tr>');
		arr.push('</table>');
		this.detailsTpl = new Ext.XTemplate(arr);

		arr = [];
		arr.push("<tr>")
		for (var i = 0, length = listArr.length; i < length; i++) {
			arr.push("<td>{");
			arr.push(listArr[i].itemCode);
			arr.push("}</td>");
		}
		arr.push("</tr>")
		this.detailRowsTpl = new Ext.XTemplate(arr);
		arr = [];
		arr.push('<table width="80%" height="30" border="0" cellpadding="0" cellspacing="0" class="container"><tr>')
		for (var i = 0, length = bottomArr.length; i < length; i++) {
//			arr.push('<td class="billFormLabel">');
			arr.push('<td>');
			arr.push(bottomArr[i].itemName);
			arr.push("</td>");
//			arr.push('<td class="billFormField">');
			arr.push('<td>');
//			arr.push(bottomArr[i].itemCode);
			arr.push("&nbsp");
			arr.push("</td>");
		}
		arr.push('</tr></table>')
		this.footerTpl = new Ext.XTemplate(arr);
//		alert(Ext.encode(this.footerTpl))

		// 分页标志
		this.pageBreakTpl = new Ext.XTemplate(
				'<span class="print-pagebreak-flag noprint">', '</span>');
	},
	showPrintWindow : function(html) {
		var opner =new Ufida.WindowOpenFun();
	    var win =opner.windowOpen("", "wwerwe", 'left=0,top=0,width='
						+ (screen.availWidth - 10) + ',height='
						+ (screen.availHeight - 55)
						+ ',toolbar=no,menubar=yes,scrollbars=yes,status=yes,location=no');	
		window.printer = this;
		win.focus();
		win.document.open("text/html", "replace");
		win.document.write(html);
		
		if(Ext.isIE8){
			setTimeout(function() {
				win.document.close();
			}, 1000);
		}else{
			setTimeout(function() {
				win.document.close();
			}, 500);
		}
	},
	// 打印全部页
	printAll : function(grid) {
		var ds = grid.store;
		var store = new Ext.data.Store({
			url : ds.proxy.url,
			params : ds.baseParams,
			autoLoad : false,
			reader : ds.reader
		});
		store.baseParams = {
			start : 0,
			limit : 10000000000,
			itemsFlag : '1'
		}
		var self = this;
		store.load({
					callback : function() {
						var rds = store.getRange();
						self.printRecords(rds);
					}
				}, this)

	},
	// 打印当前页
	printCurrent : function(grid) {
		var rds = grid.store.getRange();
		this.printRecords(rds);
	},
	// 打印选中行
	printSelected : function(grid) {
		var rds = grid.getSelectionModel().getSelections();
		if (!rds || rds.length == 0) {
			return alert('没有选中要打印的单据')
		}
		this.printRecords(rds);
	},
	// 打印传入的records
	printRecords : function(records) {
//		alert(Ext.encode(records))
		//每一条记录，包含表单、列表
		this.records = records;
		Ext.Ajax.request({
			url : '/accountMgr/printTemplate.do?method=query',
			method : 'post',
			params : {
				type : this.printType //打印单据类型（采购订单、销售签单。。。），子类定义
			},
			failure : function(result, request) {
				displayMessageBox("保存失败", "保存失败,请重试或联系客服。")
			},
			success : function(result, request) {
//				alert(result.responseText)
				var json = Ext.decode(result.responseText)
				var printSet;
				var perRow = 8;
				
				if (json.result) {//查询返回的结果集，有记录
					printSet = Ext.decode(json.result.model);
					 perRow = printSet.perRow.itemName;
				} else { //查询返回的结果集，无记录
					printSet = this.defaultItem; //缺省值，子类定义
				}
				
				try {
					//invoke method 
					this.initTpl(printSet, this.records);
					
					var body = [];
					
					for (var i = 0, len = records.length; i < len; i++) {
						if (records[i]) {
							var totalRow = records[i].data.items.length;
							var pageNum = totalRow / perRow;
							pageNum = Math.ceil(pageNum);
							
							var rowAry= new Array(pageNum);
							for(var k=0;k<pageNum;k++){
								var p = {} ;
								Ext.apply(p,records[i].data);
								var totalAry =records[i].data.items;
								p.items = totalAry.slice(k*perRow,(k+1)*perRow);
								rowAry[k] = p ;
							}
							for( var m=rowAry[pageNum-1].items.length;m<perRow;m++ ){
								rowAry[pageNum-1].items.push({});
							}
							for(var j=0;j<pageNum;j++){
								body.push(this.printBody(rowAry[j], i, len));
							}
						}else{
						}
					}
					
					this.showPrintWindow(this.documentTpl.apply({
						body : body.join('')
					}));
				} catch (e) {
					window.status = e;
				}
			},
			scope : this
		})

	},
	printBody : function(data, index, count) {
		var form = this.formTpl.apply({
			billNumber : data.oshanCode,
			storeRoom : data.storeroomName,
			inDate : data.inDate,
			remark : data.remark,
			handlingPerson : data.empName,
			srmsg : data.srName
		});
		var items = data.items; // 明细
		var totalCount = 0;
		var detailRows = [];
		for (var i = 0, len = items.length; i < len; i++) {
			totalCount += parseFloat(items[i].qty || 0);
			detailRows.push(this.detailRowsTpl.apply({
				goodsCode : items[i].stockCode,
				goodsName : items[i].stockName,
				guiGe : items[i].spec,
				danWei : items[i].changePer,
				count : items[i].qty,
				price : money(items[i].cost),
				amt : money(items[i].amt)
			}));
		}
		var detail = this.detailsTpl.apply({
			count : money(totalCount),
			totalAmt : money(data.amt),
			detailsRows : detailRows.join('')
		});
		var footer = this.footerTpl.apply({
			billPerson : data.createPerson,
			billDate :typeof(data.createDate)=='string'? data.createDate: data.createDate.format("Y-m-d") 
		});
		return this.bodyTpl.apply({
			title : AN + this.billTitle,
			form : form,
			details : detail,
			footer : footer,
			toolTip : count ? ((index + 1) + "/" + count) : ''
		});
	},
	customTpl : function(data, index, len) {
		if (!data.hasCustom
				&& (!data.templateDto || !data.templateDto.templateId))
			return '';
		var sb1 = [];
		sb1
				.push('<table width="90%" border="0" cellspacing="0" cellpadding="0" class="container">');
		var field = "property";
		var value = "propertyValue";
		var config = {};
		if (data.hasCustom) {
			for (var i = 1; i < 11; i++) {

				var j = 0;
				var sb = [];
				while (j < 3) {
					if (i > 10)
						break;
					if (data[field + i]) {
						sb.push('    <td class="billFormLabel">{');
						sb.push(field + i);
						sb.push('}</td>');
						sb.push('    <td class="billFormField">{');
						sb.push(value + i);
						sb.push('}</td>');
						config[field + i] = data[field + i];
						config[value + i] = data[value + i];
						j++;
					}
					i++;
				}
				i--;
				if (j > 0) {
					sb1.push('  <tr>');
					sb1.push(sb.join(''));
					for (var x = j; x < 3; x++) {
						sb1.push("<td>&nbsp;</td>")
					}
					sb1.push('  </tr>');
				}
			}
			sb1.push('</table>');
			sb1.join("");
			var tpl = new Ext.XTemplate(sb1);

			return tpl.apply(config);
		} else {
			for (var i = 1; i < 11; i++) {
				var j = 0;
				var sb = [];
				while (j < 3) {
					if (i > 10)
						break;
					if (data.templateDto[field + i]) {
						sb.push('    <td class="billFormLabel">{');
						sb.push(field + i);
						sb.push('}:</td>');
						sb.push('    <td class="billFormField">{');
						sb.push(value + i);
						sb.push('}</td>');
						config[field + i] = data.templateDto[field + i];
						config[value + i] = data.templateDto[value + i];
						j++;
					}
					i++;
				}
				i--;
				if (j > 0) {
					sb1.push('  <tr>');
					sb1.push(sb.join(''));
					for (var x = j; x < 3; x++) {
						sb1.push("<td>&nbsp;</td>")
					}
					sb1.push('  </tr>');
				}
			}
			sb1.push('</table>');
			sb1.join("");
			var tpl = new Ext.XTemplate(sb1);

			return tpl.apply(config);
		}
	}
});

/**
 * 打印其它入库单
 */

Ufida.IshanPrinter = new Ufida.BillListPrinter({
	billTitle : '其它入库单',
	printType : '7',
	defaultItem : {
		// ========== 表单 ==========
		'billNumber' : {
			itemCode : 'billNumber',// id
			itemName : '单据编号：',// label
			itemType : 'F',
			isShow : true
		},
		'storeRoom' : {
			itemCode : 'storeRoom',
			itemName : '仓库：',
			itemType : 'F',
			isShow : true
		},
		'inDate' : {
			itemCode : 'inDate',
			itemName : '入库日期：',
			itemType : 'F',
			isShow : true
		},
		'remark' : {
			itemCode : 'remark',
			itemName : '备注：',
			itemType : 'F',
			isShow : true
		},
		'handlingPerson' : {
			itemCode : 'handlingPerson',
			itemName : '业务员：',
			itemType : 'F',
			isShow : true
		},
		'srmsg' : {
			itemCode : 'srmsg',
			itemName : '出入库类别：',
			itemType : 'F',
			isShow : true
		},
		// ========== 列表 ==========
		'goodsCode' : {
			itemCode : 'goodsCode',
			itemName : '货品编号',
			itemType : 'L',
			isShow : true
		},
		'goodsName' : {
			itemCode : 'goodsName',
			itemName : '货品名称',
			itemType : 'L',
			isShow : true
		},
		'guiGe' : {
			itemCode : 'guiGe',
			itemName : '规格',
			itemType : 'L',
			isShow : true
		},
		'danWei' : {
			itemCode : 'danWei',
			itemName : '计量单位',
			itemType : 'L',
			isShow : true
		},
		'count' : {
			itemCode : 'count',
			itemName : '数量',
			itemType : 'L',
			isShow : true
		},
		'price' : {
			itemCode : 'price',
			itemName : '单价',
			itemType : 'L',
			isShow : true
		},
		'amt' : {
			itemCode : 'amt',
			itemName : '金额',
			itemType : 'L',
			isShow : true
		},
		// ========== 表尾 ==========
		'billPerson' : {
			itemCode : 'billPerson',
			itemName : '制单人（预览）：',
			itemType : 'B',
			isShow : true
		},
		'billDate' : {
			itemCode : 'billDate',
			itemName : '审核人（预览）：',
			itemType : 'B',
			isShow : true
		},
		'stockmanSign' : {
			itemCode : 'stockmanSign',
			itemName : '库管签字（预览）：',
			itemType : 'B',
			isShow : true
		}
	},
	printBody : function(data, index, count) {
		var form = this.formTpl.apply({
			billNumber : data.ishanCode,
			storeRoom : data.storeroomName,
			inDate : StringToDate(data.inDate),
			remark : data.remark,
			handlingPerson : data.empName,
			srmsg : data.srName
		});
		var items = data.items; // 明细
		var totalCount = 0;
		var totalAmt = 0;
		var detailRows = [];
		for (var i = 0, len = items.length; i < len; i++) {
			totalCount += parseFloat(items[i].qty|| 0);
			totalAmt += parseFloat(items[i].amt|| 0);
			detailRows.push(this.detailRowsTpl.apply({
				goodsCode : items[i].stockCode || '&nbsp;',
				goodsName : items[i].stockName,
				guiGe : items[i].spec,
				danWei : items[i].changePer,
				count : items[i].qty,
				price : money(items[i].price),
				amt : money(items[i].amt)
			}));
		}
		var detail = this.detailsTpl.apply({
			count : money(totalCount),
			amt : money(totalAmt),
			detailsRows : detailRows.join('')
		});
		var footer = this.footerTpl.apply({
			billPerson : data.createPerson,
			billDate :typeof(data.createDate)=='string'? data.createDate: data.createDate.format("Y-m-d") 
		});

		return this.bodyTpl.apply({
			title : this.billTitle,
			form : form,
			details : detail,
			footer : footer,
			toolTip : count ? ((index + 1) + "/" + count) : ''
		});
	}
});

Ufida.OshanPrinter = new Ufida.BillListPrinter({
	billTitle : '其它出库单',
	printType : '8',
	defaultItem : {
		// ========== 表单 ==========
		'billNumber' : {
			itemCode : 'billNumber',// id
			itemName : '单据编号：',// label
			itemType : 'F',
			isShow : true
		},
		'storeRoom' : {
			itemCode : 'storeRoom',
			itemName : '仓库：',
			itemType : 'F',
			isShow : true
		},
		'outDate' : {
			itemCode : 'outDate',
			itemName : '出库日期：',
			itemType : 'F',
			isShow : true
		},
		'remark' : {
			itemCode : 'remark',
			itemName : '备注：',
			itemType : 'F',
			isShow : true
		},
		'handlingPerson' : {
			itemCode : 'handlingPerson',
			itemName : '业务员：',
			itemType : 'F',
			isShow : true
		},
		'srmsg' : {
			itemCode : 'srmsg',
			itemName : '出入库类别：',
			itemType : 'F',
			isShow : true
		},
		// ========== 列表 ==========
		'goodsCode' : {
			itemCode : 'goodsCode',
			itemName : '货品编号',
			itemType : 'L',
			isShow : true
		},
		'goodsName' : {
			itemCode : 'goodsName',
			itemName : '货品名称',
			itemType : 'L',
			isShow : true
		},
		'guiGe' : {
			itemCode : 'guiGe',
			itemName : '规格',
			itemType : 'L',
			isShow : true
		},
		'danWei' : {
			itemCode : 'danWei',
			itemName : '计量单位',
			itemType : 'L',
			isShow : true
		},
		'count' : {
			itemCode : 'count',
			itemName : '数量',
			itemType : 'L',
			isShow : true
		},
		'price' : {
			itemCode : 'price',
			itemName : '单价',
			itemType : 'L',
			isShow : true
		},
		'amt' : {
			itemCode : 'amt',
			itemName : '金额',
			itemType : 'L',
			isShow : true
		},
		// ========== 表尾 ==========
		'billPerson' : {
			itemCode : 'billPerson',
			itemName : '制单人（预览）：',
			itemType : 'B',
			isShow : true
		},
		'billDate' : {
			itemCode : 'billDate',
			itemName : '审核人（预览）：',
			itemType : 'B',
			isShow : true
		},
		'stockmanSign' : {
			itemCode : 'stockmanSign',
			itemName : '库管签字（预览）：',
			itemType : 'B',
			isShow : true
		}
	},
	printBody : function(data, index, count) {
		var form = this.formTpl.apply({
			billNumber : data.oshanCode,
			storeRoom : data.storeroomName,
			outDate : StringToDate(data.outDate),
			remark : data.remark,
			handlingPerson : data.empName,
			srmsg : data.srName
		});
		var items = data.items; // 明细
		var totalCount = 0;
		var detailRows = [];
		var totalAmt = 0;
		for (var i = 0, len = items.length; i < len; i++) {
			totalCount += parseFloat(items[i].qty|| 0);
			totalAmt += parseFloat(items[i].amt|| 0);
			detailRows.push(this.detailRowsTpl.apply({
				goodsCode : items[i].stockCode || '&nbsp;',
				goodsName : items[i].stockName,
				guiGe : items[i].spec,
				danWei : items[i].changePer,
				count : items[i].qty,
				price : money(items[i].cost),
				amt : money(items[i].amt)
			}));
		}
		var detail = this.detailsTpl.apply({
			count : money(totalCount),
			amt : money(totalAmt),
			detailsRows : detailRows.join('')
		});
		var footer = this.footerTpl.apply({
			billPerson : data.createPerson,
			billDate :typeof(data.createDate)=='string'? data.createDate: data.createDate.format("Y-m-d") 
		});

		return this.bodyTpl.apply({
			title : this.billTitle,
			form : form,
			details : detail,
			footer : footer,
			toolTip : count ? ((index + 1) + "/" + count) : ''
		});
	}
});

Ufida.PurchaseOrderPrinter = new Ufida.BillListPrinter({
	billTitle : '采购订单',
	printType : '1',
	defaultItem : {
		// ========== 表单 ==========
		'billNumber' : {
			itemCode : 'billNumber',// id
			itemName : '单据编号：',// label
			itemType : 'F',
			isShow : true
		},
		'provider' : {
			itemCode : 'provider',
			itemName : '供应商：',
			itemType : 'F',
			isShow : true
		},
		'tax' : {
			itemCode : 'tax',
			itemName : '单价含税：',
			itemType : 'F',
			isShow : true
		},
		'remark' : {
			itemCode : 'remark',
			itemName : '备注：',
			itemType : 'F',
			isShow : true
		},
		'handlingPerson' : {
			itemCode : 'handlingPerson',
			itemName : '业务员：',
			itemType : 'F',
			isShow : true
		},
		'businessDate' : {
			itemCode : 'businessDate',
			itemName : '签单日期：',
			itemType : 'F',
			isShow : true
		},
		'accountPeriod' : {
			itemCode : 'accountPeriod',
			itemName : '账期(天)：',
			itemType : 'F',
			isShow : true
		},
		'limitDate' : {
			itemCode : 'limitDate',
			itemName : '到期日：',
			itemType : 'F',
			isShow : true
		},
		'preferences' : {
			itemCode : 'preferences',
			itemName : '优惠：',
			itemType : 'F',
			isShow : true
		}
		,
		'afterPreprice' : {
			itemCode : 'afterPreprice',
			itemName : '优惠后金额：',
			itemType : 'F',
			isShow : true
		},
		// ========== 列表 ==========
		'goodsCode' : {
			itemCode : 'goodsCode',
			itemName : '货品编号',
			itemType : 'L',
			isShow : true
		},
		'goodsName' : {
			itemCode : 'goodsName',
			itemName : '货品名称',
			itemType : 'L',
			isShow : true
		},
		'guiGe' : {
			itemCode : 'guiGe',
			itemName : '规格',
			itemType : 'L',
			isShow : true
		},
		'danWei' : {
			itemCode : 'danWei',
			itemName : '计量单位',
			itemType : 'L',
			isShow : true
		},
		'count' : {
			itemCode : 'count',
			itemName : '数量',
			itemType : 'L',
			isShow : true
		},
		'price' : {
			itemCode : 'price',
			itemName : '单价',
			itemType : 'L',
			isShow : true
		},
		'amt' : {
			itemCode : 'amt',
			itemName : '金额',
			itemType : 'L',
			isShow : true
		},
		// ========== 表尾 ==========
		'billPerson' : {
			itemCode : 'billPerson',
			itemName : '制单人（预览）：',
			itemType : 'B',
			isShow : true
		},
		'billDate' : {
			itemCode : 'billDate',
			itemName : '审核人（预览）：',
			itemType : 'B',
			isShow : true
		},
		'providerSign' : {
			itemCode : 'providerSign',
			itemName : '供应商签字（预览）：',
			itemType : 'B',
			isShow : true
		},
		// ========== 自定义项 ==========
		'property1' : {
			itemCode : 'propertyValue1',
			itemName : 'property1',
			itemKey : 'property1',
			itemType : 'C',
			isShow : true
		},
		'property2' : {
			itemCode : 'propertyValue2',
			itemName : 'property2',
			itemKey : 'property2',
			itemType : 'C',
			isShow : true
		},
		'property3' : {
			itemCode : 'propertyValue3',
			itemName : 'property3',
			itemKey : 'property3',
			itemType : 'C',
			isShow : true
		},
		'property4' : {
			itemCode : 'propertyValue4',
			itemName : 'property4',
			itemKey : 'property4',
			itemType : 'C',
			isShow : true
		},
		'property5' : {
			itemCode : 'propertyValue5',
			itemName : 'property5',
			itemKey : 'property5',
			itemType : 'C',
			isShow : true
		},
		'property6' : {
			itemCode : 'propertyValue6',
			itemName : 'property6',
			itemKey : 'property6',
			itemType : 'C',
			isShow : true
		},
		'property7' : {
			itemCode : 'propertyValue7',
			itemName : 'property7',
			itemKey : 'property7',
			itemType : 'C',
			isShow : true
		},
		'property8' : {
			itemCode : 'propertyValue8',
			itemName : 'property8',
			itemKey : 'property8',
			itemType : 'C',
			isShow : true
		},
		'property9' : {
			itemCode : 'propertyValue9',
			itemName : 'property9',
			itemKey : 'property9',
			itemType : 'C',
			isShow : true
		},
		'property10' : {
			itemCode : 'propertyValue10',
			itemName : 'property10',
			itemKey : 'property10',
			itemType : 'C',
			isShow : true
		}

	},
	printBody : function(data, index, count) {
		var items = data.items; // 明细
		var totalCount = 0;
		var detailRows = [];
		var totalAmt = 0;
		for (var i = 0, len = items.length; i < len; i++) {
			totalCount += parseFloat(items[i].qty|| 0);
			totalAmt += parseFloat(items[i].amt|| 0);
			detailRows.push(this.detailRowsTpl.apply({
				goodsCode : items[i].stockCode || '&nbsp;',
				goodsName : items[i].stockName ,
				guiGe : items[i].spec ,
				danWei : items[i].changePer ,
				count : items[i].qty ,
				price : money(items[i].price),
				amt : money(items[i].amt)
			}));
		}
		var form = this.formTpl.apply({
			billNumber : data.orderCode,
			businessDate : StringToDate(data.orderDate),
			accountPeriod : data.accountPeriod,
			limitDate : StringToDate(data.limitDate),
			remark : data.remark,
			provider : data.supplierName,
			handlingPerson : data.empName,
			preferences: money(data.preferences),
			afterPreprice:money(totalAmt - (data.preferences||0)),//优惠后
			tax : data.rate == 'Y' ? '含税' : "不含税"
		});
		var detail = this.detailsTpl.apply({
			count : money(totalCount),
			amt : money(data.amt || totalAmt),
			detailsRows : detailRows.join('')
		});
		var footer = this.footerTpl.apply({
			billPerson : data.createPerson,
			billDate : typeof(data.createDate)=='string'? data.createDate: data.createDate.format("Y-m-d") 
		});
		var custom = this.custTpl.apply(data.templateDto);
		return this.bodyTpl.apply({
			title : this.billTitle,
			form : form,
			details : detail,
			custom : custom,
			footer : footer,
			toolTip : count ? ((index + 1) + "/" + count) : ''
		});
	},
	formTpl : new Ext.XTemplate(
			'<table width="90%" border="0" cellspacing="0" cellpadding="0" class="container">',
			'  <tr>',
			'    <td class="billFormLabel">单据编号:</td>',
			'    <td class="billFormField" colspan="1">{billNumber}</td>',
			'  </tr>',
			'  <tr>',
			'    <td>供应商:</td>',
			'    <td class="billFormField">{provider}</td>',
			'    <td class="billFormLabel">单价含税:</td>',
			'    <td class="billFormField">{tax}</td>',
			'    <td class="billFormLabelNarrow">备注:</td>',
			'    <td class="billFormField" rowspan="2" valign="top">{remark}</td>',
			'  </tr>', '  <tr>', '    <td class="billFormLabel">业务员:</td>',
			'    <td class="billFormField">{handlingPerson}</td>',
			'    <td class="billFormLabel">签单日期:</td>',
			'	 <td class="billFormField">{businessDate}</td>', '  </tr>',
			'  <tr>', '    <td class="billFormLabel">账期(天):</td>',
			'    <td class="billFormField">{accountPeriod}</td>',
			'    <td class="billFormLabel">到期日:</td>',
			'	 <td class="billFormField">{limitDate}</td>', '  </tr>',
			'  <tr>', '    <td class="billFormLabel">优惠：</td>',
			'    <td class="billFormField">{preferences}</td>',
			'    <td class="billFormLabel">优惠后金额：</td>',
			'	 <td class="billFormField">{afterPreprice}</td>', '  </tr>',
			'</table>')
});

Ufida.PurchaseOrderNewPrinter = new Ufida.BillListPrinter({
	billTitle : '采购入库单',
	printType : '2',
	defaultItem : {
		// ========== 表单 ==========
		'billNumber' : {
			itemCode : 'billNumber',// id
			itemName : '单据编号：',// label
			itemType : 'F',
			isShow : true
		},
		'provider' : {
			itemCode : 'provider',
			itemName : '供应商：',
			itemType : 'F',
			isShow : true
		},
		'purType' : {
			itemCode : 'purType',
			itemName : '发票类型：',
			itemType : 'F',
			isShow : true
		},
		'storeRoom' : {
			itemCode : 'storeRoom',
			itemName : '仓库：',
			itemType : 'F',
			isShow : true
		},
		'businessDate' : {
			itemCode : 'businessDate',
			itemName : '采购日期：',
			itemType : 'F',
			isShow : true
		},
		'remark' : {
			itemCode : 'remark',
			itemName : '备注：',
			itemType : 'F',
			isShow : true
		},
		'handlingPerson' : {
			itemCode : 'handlingPerson',
			itemName : '业务员：',
			itemType : 'F',
			isShow : true
		},
		'sourceBillCode' : {
			itemCode : 'sourceBillCode',
			itemName : '来源采购订单：',
			itemType : 'F',
			isShow : true
		},

		'accountPeriod' : {
			itemCode : 'accountPeriod',
			itemName : '账期(天)：',
			itemType : 'F',
			isShow : true
		},
		'limitDate' : {
			itemCode : 'limitDate',
			itemName : '到期日：',
			itemType : 'F',
			isShow : true
		},
		'contact' : {
			itemCode : 'contact',
			itemName : '联系人：',
			itemType : 'F',
			isShow : true
		},
		'sendGoodsAddr' : {
			itemCode : 'sendGoodsAddr',
			itemName : '送货地址：',
			itemType : 'F',
			isShow : true
		},
		'contactTel' : {
			itemCode : 'contactTel',
			itemName : '联系人电话：',
			itemType : 'F',
			isShow : true
		},
		'preferences' : {
			itemCode : 'preferences',
			itemName : '优惠：',
			itemType : 'F',
			isShow : true
		},
		'afterPreprice' : {
			itemCode : 'afterPreprice',
			itemName : '优惠后金额：',
			itemType : 'F',
			isShow : true
		},
		// ========== 列表 ==========
		'goodsCode' : {
			itemCode : 'goodsCode',
			itemName : '货品编号',
			itemType : 'L',
			isShow : true
		},
		'goodsName' : {
			itemCode : 'goodsName',
			itemName : '货品名称',
			itemType : 'L',
			isShow : true
		},
		'guiGe' : {
			itemCode : 'guiGe',
			itemName : '规格',
			itemType : 'L',
			isShow : true
		},
		'danWei' : {
			itemCode : 'danWei',
			itemName : '计量单位',
			itemType : 'L',
			isShow : true
		},
		'count' : {
			itemCode : 'count',
			itemName : '数量',
			itemType : 'L',
			isShow : true
		},
		'price' : {
			itemCode : 'price',
			itemName : '单价',
			itemType : 'L',
			isShow : true
		},
		'amt' : {
			itemCode : 'amt',
			itemName : '无税金额',
			itemType : 'L',
			isShow : true
		},
		// add
		'taxRate' : {
			itemCode : 'taxRate',
			itemName : '税率',
			itemType : 'L',
			isShow : true
		},
		'tax' : {
			itemCode : 'tax',
			itemName : '税额',
			itemType : 'L',
			isShow : true
		},
		// ========== 表尾 ==========
		'billPerson' : {
			itemCode : 'billPerson',
			itemName : '制单人（预览）：',
			itemType : 'B',
			isShow : true
		},
		'billDate' : {
			itemCode : 'billDate',
			itemName : '审核人（预览）：',
			itemType : 'B',
			isShow : true
		},
		'providerSign' : {
			itemCode : 'providerSign',
			itemName : '供应商签字（预览）：',
			itemType : 'B',
			isShow : true
		},
		'stockmanSign' : {
			itemCode : 'stockmanSign',
			itemName : '库管签字（预览）：',
			itemType : 'B',
			isShow : true
		},
		// ========== 自定义项 ==========			preferences:data.preferences,
//			afterPreprice:data.afterPreprice,

		'property1' : {
			itemCode : 'propertyValue1',
			itemName : 'property1',
			itemKey : 'property1',
			itemType : 'C',
			isShow : true
		},
		'property2' : {
			itemCode : 'propertyValue2',
			itemName : 'property2',
			itemKey : 'property2',
			itemType : 'C',
			isShow : true
		},
		'property3' : {
			itemCode : 'propertyValue3',
			itemName : 'property3',
			itemKey : 'property3',
			itemType : 'C',
			isShow : true
		},
		'property4' : {
			itemCode : 'propertyValue4',
			itemName : 'property4',
			itemKey : 'property4',
			itemType : 'C',
			isShow : true
		},
		'property5' : {
			itemCode : 'propertyValue5',
			itemName : 'property5',
			itemKey : 'property5',
			itemType : 'C',
			isShow : true
		},
		'property6' : {
			itemCode : 'propertyValue6',
			itemName : 'property6',
			itemKey : 'property6',
			itemType : 'C',
			isShow : true
		},
		'property7' : {
			itemCode : 'propertyValue7',
			itemName : 'property7',
			itemKey : 'property7',
			itemType : 'C',
			isShow : true
		},
		'property8' : {
			itemCode : 'propertyValue8',
			itemName : 'property8',
			itemKey : 'property8',
			itemType : 'C',
			isShow : true
		},
		'property9' : {
			itemCode : 'propertyValue9',
			itemName : 'property9',
			itemKey : 'property9',
			itemType : 'C',
			isShow : true
		},
		'property10' : {
			itemCode : 'propertyValue10',
			itemName : 'property10',
			itemKey : 'property10',
			itemType : 'C',
			isShow : true
		}

	},
	printBody : function(data, index, count) {
		// 根据 是否有发票 判断 明细表格使用的模板
		var detailTpl, detailRowTpl;
		if (data.purType == 'Y') {// 有发票
			// detailTpl = this.detailsTpl_HasBill;
			// detailRowTpl = this.detailRowsTpl_HasBill
			detailTpl = this.detailsTpl;
			detailRowTpl = this.detailRowsTpl;
		} else {// 无发票
			detailTpl = this.detailsTpl;
			detailRowTpl = this.detailRowsTpl;
		}
		var items = data.items; // 明细
		var totalCount = 0;
		var detailRows = [];
		var totalTaxAmt = 0;
		var totalAmt = 0;
		for (var i = 0, len = items.length; i < len; i++) {
			totalCount += parseFloat(items[i].qty || 0);
			totalAmt += parseFloat(items[i].amt || 0);
			totalTaxAmt += parseFloat(items[i].tax || 0);
			detailRows.push(detailRowTpl.apply({
				goodsCode : items[i].stockCode,
				goodsName : items[i].stockName,
				guiGe : items[i].spec,
				danWei : items[i].changePer,
				count : items[i].qty,
				price : money(items[i].price),
				amt : money(items[i].amt),
				taxRate : money(items[i].taxRate)==''?'&nbsp;':money(items[i].taxRate) + "%",
				tax : money(items[i].tax)
			}));
		}
		var form = this.formTpl.apply({
			billNumber : data.purCode,
			businessDate : StringToDate(data.purDate),
			limitDate :  StringToDate(data.limitDate),
			accountPeriod : data.accountPeriod,
			remark : data.remark,
			provider : data.supplierName,
			handlingPerson : data.empName,
			storeRoom : data.storeroomName,
			sourceBillCode : data.sourceBillCode,
			purType : data.purType == 'Y' ? '有发票' : '无发票',
			contact : data.contactPerson,
			sendGoodsAddr : data.addr,
			afterPreprice:money(totalAmt - (data.preferences||0)),//优惠后
			preferences: money(data.preferences),
			contactTel : data.contanttel
		});
		var detail = detailTpl.apply({
			count : money(totalCount),
			amt : money(data.amt || totalAmt),
			tax : money(totalTaxAmt),
			detailsRows : detailRows.join('')
		});
		var footer = this.footerTpl.apply({
			billPerson : data.createPerson,
			billDate :typeof(data.createDate)=='string'? data.createDate: data.createDate.format("Y-m-d")
		});
		var custom = this.custTpl.apply(data.templateDto);
		return this.bodyTpl.apply({
			title : this.billTitle,
			form : form,
			custom : custom,
			details : detail,
			footer : footer,
			toolTip : count ? ((index + 1) + "/" + count) : ''
		});
	}
});

Ufida.PurchaseBackNewPrinter = new Ufida.BillListPrinter({
	billTitle : '采购退货单',
	printType : '3',
	defaultItem : {
		// ========== 表单 ==========
		'billNumber' : {
			itemCode : 'billNumber',// id
			itemName : '单据编号：',// label
			itemType : 'F',
			isShow : true
		},
		'provider' : {
			itemCode : 'provider',
			itemName : '供应商：',
			itemType : 'F',
			isShow : true
		},
		'purType' : {
			itemCode : 'purType',
			itemName : '发票类型：',
			itemType : 'F',
			isShow : true
		},
		'storeRoom' : {
			itemCode : 'storeRoom',
			itemName : '仓库：',
			itemType : 'F',
			isShow : true
		},
		'businessDate' : {
			itemCode : 'businessDate',
			itemName : '退货日期：',
			itemType : 'F',
			isShow : true
		},
		'remark' : {
			itemCode : 'remark',
			itemName : '备注：',
			itemType : 'F',
			isShow : true
		},
		'handlingPerson' : {
			itemCode : 'handlingPerson',
			itemName : '业务员：',
			itemType : 'F',
			isShow : true
		},
		'sourceBillCode' : {
			itemCode : 'sourceBillCode',
			itemName : '来源采购单：',
			itemType : 'F',
			isShow : true
		},
		// ========== 列表 ==========
		'stockCode' : {
			itemCode : 'stockCode',
			itemName : '货品编号',
			itemType : 'L',
			isShow : true
		},
		'stockName' : {
			itemCode : 'stockName',
			itemName : '货品名称',
			itemType : 'L',
			isShow : true
		},
		'spec' : {
			itemCode : 'spec',
			itemName : '规格',
			itemType : 'L',
			isShow : true
		},
		'changePer' : {
			itemCode : 'changePer',
			itemName : '计量单位',
			itemType : 'L',
			isShow : true
		},
		'qty' : {
			itemCode : 'qty',
			itemName : '退货数量',
			itemType : 'L',
			isShow : true
		},
		'price' : {
			itemCode : 'price',
			itemName : '单价',
			itemType : 'L',
			isShow : true
		},
		'amt' : {
			itemCode : 'amt',
			itemName : '金额',
			itemType : 'L',
			isShow : true
		},
		// add
		'taxRate' : {
			itemCode : 'taxRate',
			itemName : '税率',
			itemType : 'L',
			isShow : true
		},
		'tax' : {
			itemCode : 'tax',
			itemName : '税额',
			itemType : 'L',
			isShow : true
		},
		// ========== 表尾 ==========
//		'billPerson' : {
//			itemCode : 'billPerson',
//			itemName : '制单人：',
//			itemType : 'B',
//			isShow : true
//		},
//		'billDate' : {
//			itemCode : 'billDate',
//			itemName : '制单日期：',
//			itemType : 'B',
//			isShow : true
//		}
		'billPerson' : {
			itemCode : 'billPerson',
			itemName : '制单人（预览）：',
			itemType : 'B',
			isShow : true
		},
		'billDate' : {
			itemCode : 'billDate',
			itemName : '审核人（预览）：',
			itemType : 'B',
			isShow : true
		},
		'providerSign' : {
			itemCode : 'providerSign',
			itemName : '供应商签字（预览）：',
			itemType : 'B',
			isShow : true
		},
		'stockmanSign' : {
			itemCode : 'stockmanSign',
			itemName : '库管签字（预览）：',
			itemType : 'B',
			isShow : true
		}
	},
	printBody : function(data, index, count) {
		var form = this.formTpl.apply({
			billNumber : data.backCode,
			businessDate : StringToDate( data.backDate),
			limitDate :StringToDate( data.limitDate),
			accountPeriod : data.accountPeriod,
			remark : data.remark,
			provider : data.supplierName,
			handlingPerson : data.empName,
			storeRoom : data.storeroomName,
			sourceBillCode : data.sourceBillCode,
			purType : data.backType == 'Y' ? '有发票' : '无发票',
			contact : data.contactPerson,
			sendGoodsAddr : data.addr,
			contactTel : data.contanttel
		});
		// 根据 是否有发票 判断 明细表格使用的模板
		var detailTpl, detailRowTpl;
		if (data.purType == 'Y') {// 有发票
			// detailTpl = this.detailsTpl_HasBill;
			// detailRowTpl = this.detailRowsTpl_HasBill
			detailTpl = this.detailsTpl;
			detailRowTpl = this.detailRowsTpl;
		} else {// 无发票
			detailTpl = this.detailsTpl;
			detailRowTpl = this.detailRowsTpl;
		}
		var items = data.items; // 明细
		var totalCount = 0;
		var detailRows = [];
		var totalTaxAmt = 0;
		var totalAmt = 0;
		for (var i = 0, len = items.length; i < len; i++) {
			totalCount += parseFloat(items[i].qty|| 0);
			totalAmt += parseFloat(items[i].amt|| 0);
			totalTaxAmt += parseFloat(items[i].tax || 0);
			detailRows.push(detailRowTpl.apply({
				stockCode : items[i].stockCode,
				stockName : items[i].stockName,
				spec : items[i].spec,
				changePer : items[i].changePer,
				qty : items[i].qty,
				price : money(items[i].price),
				amt : money(items[i].amt),
				taxRate : money(items[i].taxRate)==''?'&nbsp;':money(items[i].taxRate) + "%",
				tax : money(items[i].tax)
			}));
		}
		var detail = detailTpl.apply({
			qty : money(totalCount),
			amt : money(data.amt || totalAmt),
			tax : money(totalTaxAmt),
			detailsRows : detailRows.join('')
		});
		var footer = this.footerTpl.apply({
			billPerson : data.createPerson,
			billDate : typeof(data.createDate)=='string'? data.createDate: data.createDate.format("Y-m-d") 
		});
		return this.bodyTpl.apply({
			title : this.billTitle,
			form : form,
			details : detail,
			footer : footer,
			toolTip : count ? ((index + 1) + "/" + count) : ''
		});
	}
});

Ufida.SaleOrderPrinter = new Ufida.BillListPrinter({
	billTitle : '销售签单',
	printType : '4',
	defaultItem : {
		// ========== 表单 ==========
		'billNumber' : {
			itemCode : 'billNumber',// id
			itemName : '单据编号：',// label
			itemType : 'F',
			isShow : true
		},
		'tax' : {
			itemCode : 'tax',
			itemName : '单价含税：',
			itemType : 'F',
			isShow : true
		},
		'remark' : {
			itemCode : 'remark',
			itemName : '备注：',
			itemType : 'F',
			isShow : true
		},
		'client' : {
			itemCode : 'client',
			itemName : '客户：',
			itemType : 'F',
			isShow : true
		},
		'businessDate' : {
			itemCode : 'businessDate',
			itemName : '签单日期：',
			itemType : 'F',
			isShow : true
		},
		'handlingPerson' : {
			itemCode : 'handlingPerson',
			itemName : '业务员：',
			itemType : 'F',
			isShow : true
		},
		'deliverDate' : {
			itemCode : 'deliverDate',
			itemName : '交货日期：',
			itemType : 'F',
			isShow : true
		},
		'accountPeriod' : {
			itemCode : 'accountPeriod',
			itemName : '账期(天)：',
			itemType : 'F',
			isShow : true
		},
		'limitDate' : {
			itemCode : 'limitDate',
			itemName : '到期日：',
			itemType : 'F',
			isShow : true
		},
		'preferences' : {
			itemCode : 'preferences',
			itemName : '优惠：',
			itemType : 'F',
			isShow : true
		},
		'afterPreprice' : {
			itemCode : 'afterPreprice',
			itemName : '优惠后金额：',
			itemType : 'F',
			isShow : true
		},
		// ========== 列表 ==========
		'goodsNum' : {
			itemCode : 'goodsNum',
			itemName : '货品编号',
			itemType : 'L',
			isShow : true
		},
		'goodsName' : {
			itemCode : 'goodsName',
			itemName : '货品名称',
			itemType : 'L',
			isShow : true
		},
		'standard' : {
			itemCode : 'standard',
			itemName : '规格',
			itemType : 'L',
			isShow : true
		},
		'measureUnit' : {
			itemCode : 'measureUnit',
			itemName : '计量单位',
			itemType : 'L',
			isShow : true
		},
		'amount' : {
			itemCode : 'amount',
			itemName : '数量',
			itemType : 'L',
			isShow : true
		},
		'beforeDiscount' : {
			itemCode : 'beforeDiscount',
			itemName : '折前价',
			itemType : 'L',
			isShow : true
		},
		'discountRate' : {
			itemCode : 'discountRate',
			itemName : '折扣率',
			itemType : 'L',
			isShow : true
		},
		'discountPrice' : {
			itemCode : 'discountPrice',
			itemName : '折扣额',
			itemType : 'L',
			isShow : true
		},
		'afterDiscount' : {
			itemCode : 'afterDiscount',
			itemName : '折后价',
			itemType : 'L',
			isShow : true
		},
		'price' : {
			itemCode : 'price',
			itemName : '金额',
			itemType : 'L',
			isShow : true
		},
		// ========== 表尾 ==========
		'billPerson' : {
			itemCode : 'billPerson',
			itemName : '制单人（预览）：',
			itemType : 'B',
			isShow : true
		},
		'billDate' : {
			itemCode : 'billDate',
			itemName : '审核人（预览）：',
			itemType : 'B',
			isShow : true
		},
		'providerSign' : {
			itemCode : 'providerSign',
			itemName : '供应商签字（预览）：',
			itemType : 'B',
			isShow : true
		},
		// ========== 自定义项 ==========
		'property1' : {
			itemCode : 'propertyValue1',
			itemName : 'property1',
			itemKey : 'property1',
			itemType : 'C',
			isShow : true
		},
		'property2' : {
			itemCode : 'propertyValue2',
			itemName : 'property2',
			itemKey : 'property2',
			itemType : 'C',
			isShow : true
		},
		'property3' : {
			itemCode : 'propertyValue3',
			itemName : 'property3',
			itemKey : 'property3',
			itemType : 'C',
			isShow : true
		},
		'property4' : {
			itemCode : 'propertyValue4',
			itemName : 'property4',
			itemKey : 'property4',
			itemType : 'C',
			isShow : true
		},
		'property5' : {
			itemCode : 'propertyValue5',
			itemName : 'property5',
			itemKey : 'property5',
			itemType : 'C',
			isShow : true
		},
		'property6' : {
			itemCode : 'propertyValue6',
			itemName : 'property6',
			itemKey : 'property6',
			itemType : 'C',
			isShow : true
		},
		'property7' : {
			itemCode : 'propertyValue7',
			itemName : 'property7',
			itemKey : 'property7',
			itemType : 'C',
			isShow : true
		},
		'property8' : {
			itemCode : 'propertyValue8',
			itemName : 'property8',
			itemKey : 'property8',
			itemType : 'C',
			isShow : true
		},
		'property9' : {
			itemCode : 'propertyValue9',
			itemName : 'property9',
			itemKey : 'property9',
			itemType : 'C',
			isShow : true
		},
		'property10' : {
			itemCode : 'propertyValue10',
			itemName : 'property10',
			itemKey : 'property10',
			itemType : 'C',
			isShow : true
		}

	},
	printBody : function(data, index, count) {
	
		var items = data.items; // 明细
		var totalCount = 0;
		var detailRows = [];
		var totalAmt = 0;
		var totalDiscountAmt = 0;
		for (var i = 0, len = items.length; i < len; i++) {
			totalCount += parseFloat(items[i].amount|| 0);
			totalAmt += parseFloat(items[i].price|| 0);
			totalDiscountAmt += parseFloat(items[i].discountPrice|| 0);
			detailRows.push(this.detailRowsTpl.apply({
				goodsNum : items[i].goodsNum || '&nbsp;',
				goodsName : items[i].goodsName,
				standard : items[i].standard,
				measureUnit : items[i].measureUnit,
				amount : items[i].amount,
				beforeDiscount : money(items[i].beforeDiscount),
				discountRate : money(items[i].discountRate),
				discountPrice : money(items[i].discountPrice),
				afterDiscount : money(items[i].afterDiscount),
				price : money(items[i].price)
			}));
		}
		var form = this.formTpl.apply({
			billNumber : data.saleorderNum,
			deliverDate : StringToDate(data.deliverDate),
			businessDate : StringToDate(data.orderDate),
			limitDate : StringToDate(data.limitDate),
			accountPeriod : data.accountPeriod,
			remark : data.note,
			client : data.clientName,
			handlingPerson : data.busspeoName,
			tax : data.rate == 'Y' ? '含税' : "不含税",
			preferences : money(data.preferences),
			afterPreprice:money(totalAmt - (data.preferences||0))//优惠后
		});
		var detail = this.detailsTpl.apply({
			amount : money(totalCount),
			price : money(data.amt || totalAmt),
			// discountPrice : money(totalDiscountAmt || 0),
			detailsRows : detailRows.join('')
		});
var footer = this.footerTpl.apply({
			billPerson : data.doformPeo,
			billDate : typeof(data.doformDate)=='string'? data.doformDate: data.doformDate.format("Y-m-d") 
		});
		var custom = this.custTpl.apply(data.templateDto);
		return this.bodyTpl.apply({
			title : this.billTitle,
			form : form,
			custom : custom,
			details : detail,
			footer : footer,
			toolTip : count ? ((index + 1) + "/" + count) : ''
		});
	}
});

Ufida.AddRetGoodsPrinter = new Ufida.BillListPrinter({
	billTitle : '销售退货单',
	printType : '6',
	defaultItem : {
		// ========== 表单 ==========
		'billNumber' : {
			itemCode : 'billNumber',// id
			itemName : '单据编号：',// label
			itemType : 'F',
			isShow : true
		},
		'client' : {
			itemCode : 'client',
			itemName : '客户：',
			itemType : 'F',
			isShow : true
		},
		'purType' : {
			itemCode : 'purType',
			itemName : '发票类型：',
			itemType : 'F',
			isShow : true
		},
		'storeRoom' : {
			itemCode : 'storeRoom',
			itemName : '仓库：',
			itemType : 'F',
			isShow : true
		},
		'businessDate' : {
			itemCode : 'businessDate',
			itemName : '退货日期：',
			itemType : 'F',
			isShow : true
		},
		'remark' : {
			itemCode : 'remark',
			itemName : '备注：',
			itemType : 'F',
			isShow : true
		},
		'handlingPerson' : {
			itemCode : 'handlingPerson',
			itemName : '业务员：',
			itemType : 'F',
			isShow : true
		},
		'sourceBillCode' : {
			itemCode : 'sourceBillCode',
			itemName : '来源采购单：',
			itemType : 'F',
			isShow : true
		},
		// ========== 列表 ==========
		'goodsNum' : {
			itemCode : 'goodsNum',
			itemName : '货品编号',
			itemType : 'L',
			isShow : true
		},
		'goodsName' : {
			itemCode : 'goodsName',
			itemName : '货品名称',
			itemType : 'L',
			isShow : true
		},
		'standard' : {
			itemCode : 'standard',
			itemName : '规格',
			itemType : 'L',
			isShow : true
		},
		'measureUnit ' : {
			itemCode : 'measureUnit',
			itemName : '计量单位',
			itemType : 'L',
			isShow : true
		},
		'amount ' : {
			itemCode : 'amount',
			itemName : '退货数量',
			itemType : 'L',
			isShow : true
		},
		'eachPrice ' : {
			itemCode : 'eachPrice',
			itemName : '单价',
			itemType : 'L',
			isShow : true
		},
		'price ' : {
			itemCode : 'price',
			itemName : '金额',
			itemType : 'L',
			isShow : true
		},
		'taxRate ' : {
			itemCode : 'taxRate',
			itemName : '税率',
			itemType : 'L',
			isShow : true
		},
		'texPrice' : {
			itemCode : 'texPrice',
			itemName : '税额',
			itemType : 'L',
			isShow : true
		},
		'contexPrice' : {
			itemCode : 'contexPrice',
			itemName : '含税金额',
			itemType : 'L',
			isShow : true
		},
		// ========== 表尾 ==========
		'billPerson' : {
			itemCode : 'billPerson',
			itemName : '制单人（预览）：',
			itemType : 'B',
			isShow : true
		},
		'billDate' : {
			itemCode : 'billDate',
			itemName : '审核人（预览）：',
			itemType : 'B',
			isShow : true
		},
		'providerSign' : {
			itemCode : 'providerSign',
			itemName : '客户签字（预览）：',
			itemType : 'B',
			isShow : true
		},
		'stockmanSign' : {
			itemCode : 'stockmanSign',
			itemName : '库管签字（预览）：',
			itemType : 'B',
			isShow : true
		}
	},
	printBody : function(data, index, count) {
		var form = this.formTpl.apply({
			billNumber : data.saleretNum,
			businessDate : StringToDate(data.retDate),
			remark : data.note,
			client : data.clientName,
			handlingPerson : data.busspeoName,
			storeRoom : data.storeroomName,
			sourceBillCode : data.sourceNum,
			purType : data.invoiceType == '2' ? '有发票' : '无发票'
		});
		// 根据 是否有发票 判断 明细表格使用的模板
		var detailTpl, detailRowTpl;
		if (data.invoiceType == 'Y') {// 有发票
			// detailTpl = this.detailsTpl_HasBill;
			// detailRowTpl = this.detailRowsTpl_HasBill
			detailTpl = this.detailsTpl;
			detailRowTpl = this.detailRowsTpl;
		} else {// 无发票
			detailTpl = this.detailsTpl;
			detailRowTpl = this.detailRowsTpl;
		}
		var items = data.items; // 明细
		var totalCount = 0;
		var detailRows = [];
		var totalTaxAmt = 0;
		var totalAmt = 0;
		for (var i = 0, len = items.length; i < len; i++) {
			totalCount += parseFloat(items[i].amount|| 0);
			totalAmt += parseFloat(items[i].price|| 0);
			totalTaxAmt += parseFloat(items[i].contexPrice || 0);
			detailRows.push(detailRowTpl.apply({
				goodsNum : items[i].goodsNum,
				goodsName : items[i].goodsName,
				standard : items[i].standard,
				measureUnit : items[i].measureUnit,
				amount : items[i].amount,
				eachPrice : money(items[i].eachPrice),
				price : money(items[i].price),
				taxRate : money(items[i].texRate)==''?'&nbsp;':money(items[i].texRate) + "%",
				texPrice : money(items[i].texPrice),
				contexPrice : money(items[i].contexPrice)
			}));
		}
		var detail = detailTpl.apply({
			amount : money(totalCount),
			price : money(data.amt || totalAmt),
			contexPrice : money(totalTaxAmt),
			detailsRows : detailRows.join('')
		});
		var footer = this.footerTpl.apply({
			billPerson : data.doformPeo,
			billDate : typeof(data.doformDate)=='string'? data.doformDate: data.doformDate.format("Y-m-d") 
		});
		return this.bodyTpl.apply({
			title : this.billTitle,
			form : form,
			details : detail,
			footer : footer,
			toolTip : count ? ((index + 1) + "/" + count) : ''
		});
	}
});

Ufida.SaleSendPrinter = new Ufida.BillListPrinter({
	billTitle : '销售出库单',
	printType : '5',
	defaultItem : {
		// ========== 表单 ==========
		'billNumber' : {
			itemCode : 'billNumber',// id
			itemName : '单据编号：',// label
			itemType : 'F',
			isShow : true
		},
		'client' : {
			itemCode : 'client',
			itemName : '客户：',
			itemType : 'F',
			isShow : true
		},
		'purType' : {
			itemCode : 'purType',
			itemName : '发票类型：',
			itemType : 'F',
			isShow : true
		},
		'remark' : {
			itemCode : 'remark',
			itemName : '备注：',
			itemType : 'F',
			isShow : true
		},
		'handlingPerson' : {
			itemCode : 'handlingPerson',
			itemName : '业务员：',
			itemType : 'F',
			isShow : true
		},
		'businessDate' : {
			itemCode : 'businessDate',
			itemName : '销售日期：',
			itemType : 'F',
			isShow : true
		},
		'storeRoom' : {
			itemCode : 'storeRoom',
			itemName : '仓库：',
			itemType : 'F',
			isShow : true
		},
		'srcBill' : {
			itemCode : 'srcBill',
			itemName : '来源销售签单：',
			itemType : 'F',
			isShow : true
		},
		'accountPeriod' : {
			itemCode : 'accountPeriod',
			itemName : '账期(天)：',
			itemType : 'F',
			isShow : true
		},
		'limitDate' : {
			itemCode : 'limitDate',
			itemName : '到期日：',
			itemType : 'F',
			isShow : true
		},
		'contact' : {
			itemCode : 'contact',
			itemName : '联系人：',
			itemType : 'F',
			isShow : true
		},
		'rcvGoodsAddr' : {
			itemCode : 'rcvGoodsAddr',
			itemName : '收货地址：',
			itemType : 'F',
			isShow : true
		},
		'contactTel' : {
			itemCode : 'contactTel',
			itemName : '联系人电话：',
			itemType : 'F',
			isShow : true
		},
		'preferences' : {
			itemCode : 'preferences',
			itemName : '优惠：',
			itemType : 'F',
			isShow : true
		},
		'afterPreprice' : {
			itemCode : 'afterPreprice',
			itemName : '优惠后金额：',
			itemType : 'F',
			isShow : true
		},
		// ========== 列表 ==========
		'goodsNum' : {
			itemCode : 'goodsNum',
			itemName : '货品编号',
			itemType : 'L',
			isShow : true
		},
		'goodsName' : {
			itemCode : 'goodsName',
			itemName : '货品名称',
			itemType : 'L',
			isShow : true
		},
		'standard' : {
			itemCode : 'standard',
			itemName : '规格',
			itemType : 'L',
			isShow : true
		},
		'measureUnit ' : {
			itemCode : 'measureUnit',
			itemName : '计量单位',
			itemType : 'L',
			isShow : true
		},
		'amount ' : {
			itemCode : 'amount',
			itemName : '数量',
			itemType : 'L',
			isShow : true
		},
		'eachPrice ' : {
			itemCode : 'eachPrice',
			itemName : '单价',
			itemType : 'L',
			isShow : true
		},
		'price ' : {
			itemCode : 'price',
			itemName : '金额',
			itemType : 'L',
			isShow : true
		},
		'texRate ' : {
			itemCode : 'texRate',
			itemName : '税率',
			itemType : 'L',
			isShow : true
		},
		'texPrice' : {
			itemCode : 'texPrice',
			itemName : '税额',
			itemType : 'L',
			isShow : true
		},
		'contexPrice' : {
			itemCode : 'contexPrice',
			itemName : '含税金额',
			itemType : 'L',
			isShow : true
		},
		// ========== 表尾 ==========
		'billPerson' : {
			itemCode : 'billPerson',
			itemName : '制单人（预览）：',
			itemType : 'B',
			isShow : true
		},
		'billDate' : {
			itemCode : 'billDate',
			itemName : '审核人（预览）：',
			itemType : 'B',
			isShow : true
		},
		'providerSign' : {
			itemCode : 'providerSign',
			itemName : '客户签字（预览）：',
			itemType : 'B',
			isShow : true
		},
		'stockmanSign' : {
			itemCode : 'stockmanSign',
			itemName : '库管签字（预览）：',
			itemType : 'B',
			isShow : true
		},
		// ========== 自定义项 ==========
		'property1' : {
			itemCode : 'propertyValue1',
			itemName : 'property1',
			itemKey : 'property1',
			itemType : 'C',
			isShow : true
		},
		'property2' : {
			itemCode : 'propertyValue2',
			itemName : 'property2',
			itemKey : 'property2',
			itemType : 'C',
			isShow : true
		},
		'property3' : {
			itemCode : 'propertyValue3',
			itemName : 'property3',
			itemKey : 'property3',
			itemType : 'C',
			isShow : true
		},
		'property4' : {
			itemCode : 'propertyValue4',
			itemName : 'property4',
			itemKey : 'property4',
			itemType : 'C',
			isShow : true
		},
		'property5' : {
			itemCode : 'propertyValue5',
			itemName : 'property5',
			itemKey : 'property5',
			itemType : 'C',
			isShow : true
		},
		'property6' : {
			itemCode : 'propertyValue6',
			itemName : 'property6',
			itemKey : 'property6',
			itemType : 'C',
			isShow : true
		},
		'property7' : {
			itemCode : 'propertyValue7',
			itemName : 'property7',
			itemKey : 'property7',
			itemType : 'C',
			isShow : true
		},
		'property8' : {
			itemCode : 'propertyValue8',
			itemName : 'property8',
			itemKey : 'property8',
			itemType : 'C',
			isShow : true
		},
		'property9' : {
			itemCode : 'propertyValue9',
			itemName : 'property9',
			itemKey : 'property9',
			itemType : 'C',
			isShow : true
		},
		'property10' : {
			itemCode : 'propertyValue10',
			itemName : 'property10',
			itemKey : 'property10',
			itemType : 'C',
			isShow : true
		}
	},
	printBody : function(data, index, count) {
		// 根据 是否有发票 判断 明细表格使用的模板
		var detailTpl, detailRowTpl;
		if (data.invoiceType == '2') {// 有发票
			// detailTpl = this.detailsTpl_HasBill;
			// detailRowTpl = this.detailRowsTpl_HasBill;

			detailTpl = this.detailsTpl;
			detailRowTpl = this.detailRowsTpl;
		} else {// 无发票
			detailTpl = this.detailsTpl;
			detailRowTpl = this.detailRowsTpl;
		}
		var items = data.items; // 明细
		var totalCount = 0;
		var detailRows = [];
		var totalAmt = 0;
		var totalTaxAmt = 0;
		var totalConTaxAmt = 0;
		for (var i = 0, len = items.length; i < len; i++) {
			totalCount += parseFloat(items[i].amount|| 0);
			totalAmt += parseFloat(items[i].price|| 0);
			totalTaxAmt += parseFloat(items[i].texPrice || 0);
			totalConTaxAmt += parseFloat(items[i].contexPrice || 0);
			detailRows.push(detailRowTpl.apply({
				goodsNum : items[i].goodsNum || '&nbsp;',
				goodsName : items[i].goodsName || '&nbsp;',
				standard : items[i].standard || '&nbsp;',
				measureUnit : items[i].measureUnit|| '&nbsp;',
				amount : items[i].amount|| '&nbsp;',
				eachPrice : money(items[i].eachPrice),
				price : money(items[i].price),
				texRate : money(items[i].texRate)==''?'&nbsp;':money(items[i].texRate) + "%",
				texPrice : money(items[i].texPrice),
				contexPrice : money(items[i].contexPrice)
			}));
		}
		var form = this.formTpl.apply({
			billNumber : data.salesendNum,
			businessDate :StringToDate( data.saleDate),
			limitDate :StringToDate( data.limitDate),
			accountPeriod : data.accountPeriod,
			remark : data.note,
			client : data.clientName,
			handlingPerson : data.busspeoName,
			srcBill : data.sourceNum,
			storeRoom : data.storeroomName,
			purType : data.invoiceType == '2' ? '有发票' : '无发票',
			contact : data.contactPerson,
			rcvGoodsAddr : data.addr,
			contactTel : data.contanttel,
			preferences : money(data.preferences),
			afterPreprice:money(totalAmt - (data.preferences||0))//优惠后
		});
		var detail = detailTpl.apply({
			amount : money(totalCount),
			price : money(data.amt || totalAmt),
			// taxAmt : money(totalTaxAmt),
			contexPrice : money(totalConTaxAmt),
			detailsRows : detailRows.join('')
		});
		var footer = this.footerTpl.apply({
			billPerson : data.doformPeo,
			billDate : typeof(data.doformDate)=='string'? data.doformDate: data.doformDate.format("Y-m-d") 
		});
		var custom = this.custTpl.apply(data.templateDto);
		return this.bodyTpl.apply({
			title : this.billTitle,
			form : form,
			custom : custom,
			details : detail,
			footer : footer,
			toolTip : count ? ((index + 1) + "/" + count) : ''
		});
	}

});

/**
 * *******************************************************************************
 * 进销存单据打印 End
 * *******************************************************************************
 */



/**
 * TriggerField、ComboBox、Fields
 */
Ext.override(Ext.form.TriggerField, {
			hideTriggers : function() {
				if (!this.trigger)
					return;
				var ts = this.trigger.select('.x-form-trigger', true);
				ts.each(function(t, all, index) {
					t.hide();
				});
				this.trigger.setStyle('display', 'none');
			},
			showTriggers : function() {
				if (!this.trigger)
					return;
				this.trigger.setStyle('display', 'inline');
				var ts = this.trigger.select('.x-form-trigger', true);
				ts.each(function(t, all, index) {
					t.show();
				});
			}
		});
		
Ext.override(Ext.form.DateField, {
			hideTriggers : function() {
				if (this.trigger.isVisible()) {
					this.trigger.hide();
					this.el.setWidth(this.el.getWidth()
							+ this.trigger.getWidth());
				}
				this.trigger.setStyle('display', 'none');
				if (this.keyNav) {
					this.keyNav.disable();
				}
			},
			showTriggers : function() {
				if (!this.trigger.isVisible()) {
					this.trigger.show();
					this.el.setWidth(this.el.getWidth()
							- this.trigger.getWidth());
				}
				this.trigger.setStyle('display', 'inline');
				if (this.keyNav) {
					this.keyNav.enable();
				}
			}

		});

Ext.override(Ext.form.ComboBox, {
			expand : function() {
				if (this.isExpanded() || !this.hasFocus || this.disabled
						|| this.triggerHidden === true) {
					return;
				}
				this.list.alignTo(this.wrap, this.listAlign);
				this.list.show();
				this.innerList.setOverflow('auto'); // necessary for FF 2.0/Mac
				Ext.getDoc().on('mousewheel', this.collapseIf, this);
				Ext.getDoc().on('mousedown', this.collapseIf, this);
				this.fireEvent('expand', this);
			},
			hideTriggers : function() {
				if (this.trigger.isVisible()) {
					this.trigger.hide();
					this.el.setWidth(this.el.getWidth()
							+ this.trigger.getWidth());
				}
				this.trigger.setStyle('display', 'none');
				if (this.keyNav) {
					this.keyNav.disable();
				}
			},
			showTriggers : function() {
				if (!this.trigger.isVisible()) {
					this.trigger.show();
					this.el.setWidth(this.el.getWidth()
							- this.trigger.getWidth());
				}
				this.trigger.setStyle('display', 'inline');
				if (this.keyNav) {
					this.keyNav.enable();
				}
			}
		});

Ext.override(Ext.form.Field, {
			hideAllTriggers : function() {
				if (this.trigger) {
					this.hideTriggers();
					this.triggerHidden = true;
				}
			},
			showAllTriggers : function() {
				if (this.trigger) {
					this.showTriggers();
					this.triggerHidden = false;
				}
			},
			disableEdit : function() {
				this.un('render', this.doEnableEdit);
				this.un('render', this.doDisableEdit)
				if (this.el) {
					this.doDisableEdit();
				} else {
					this.on('render', this.doDisableEdit);
				}
			},
			enableEdit : function() {
				this.un('render', this.doDisableEdit);
				this.un('render', this.doEnableEdit);
				if (this.el) {
					this.doEnableEdit();
				} else {
					this.on('render', this.doEnableEdit);
				}
			},
			doDisableEdit : function() {
				if (this.getGroupValue) {// radio or checkbox
					if (this.getValue() === false) {
						this.disable();
					}
				}
				this.el.setOpacity(0.5);
				this.oldReadOnly = this.oldReadOnly || this.el.dom.readyOnly; // 保存readOnly属性值
				Ext.getDom(this.id).readOnly = true;
				this.el.dom.readyOnly = true;
				this.hideAllTriggers();
				this.blur();
				this.editDisabled = true;

			},
			doEnableEdit : function() {
				if (this.getGroupValue) {// radio or checkbox
					this.enable();
				}
				this.el.setOpacity(1);
				Ext.getDom(this.id).readOnly = this.oldReadOnly || false;
				this.el.dom.readyOnly = this.oldReadOnly || false;
				delete this.oldReadOnly;
				this.showAllTriggers();
				this.editDisabled = false;

			},
			disableLabel : function() {
				var labelEl = this.getLabelEl();
				if (labelEl) {
					labelEl.addClass('disableEdit');
					if (this.hideRequireFlagWhenDisabled === true
							&& this.allowBlank == false) {
						var requireFlag = labelEl.down('.requireFlag');
						if (requireFlag) {
							requireFlag.hide();
						}
					}
				}
			},
			enableLabel : function() {
				var labelEl = this.getLabelEl();
				if (labelEl) {
					labelEl.removeClass('disableEdit');
					if (this.hideRequireFlagWhenDisabled === true
							&& this.allowBlank == false) {
						var requireFlag = labelEl.down('.requireFlag');
						if (requireFlag) {
							requireFlag.show();
						}
					}
				}
			},
			disableField : function() {
				this.disableEdit();
				this.disableLabel();
			},
			enableField : function() {
				this.enableEdit();
				this.enableLabel();
			},
			getLabelText : function() {
				return Ext.util.Format.stripTags(this.fieldLabel);
			},
			getLabelEl : function() {
				if (this.el) {
					var formItem = this.el.up('.x-form-item');
					if( formItem ){
						var label = formItem.child('label', false);
						return Ext.get(label);
					}
				}
				return null;
			},
			getInputFieldEl : function() {
				var formItem = this.el.up('.x-form-item');
				if (formItem) {
					var input = formItem.child('input', false);
					return Ext.get(input);
				}
				return null;
			},
			getTotalWidth : function() {
				var width = this.el.getWidth();
				if (this.trigger) {
					// alert(this.constructor.xtype+" --- "+
					// this.trigger.getWidth());
					width = width + this.trigger.getWidth();
				}
				return width;
			}

		});
Ext.QuickTips.init();
// 自定义项管理器
CustomManager = function() {

	CustomManager.superclass.constructor.call(this);
	this.addEvents({
		'load' : true,
		'loaditemssuccess' : true,
		'loaditemsfail' : true
	});
	this.breakWord = function(value) {
		if (Ext.isIE)
			return value

		var s, c = String.fromCharCode('8203');
		s = trim(value).split('').join(c);

		return s;
	}
	/**
	 * form 是提交的标单 container是容器存放自定义项
	 */
	this.addItems = function(form, container, jsonData, config, quotetype,fieldLabelHeader) {
		if (!jsonData.result[0]["templateId"]) {
			form.hasTemplate = false;
			return;
		}
		var pvalus = {};

		if (form.customProperty) {
			pvalus = Ext.urlDecode(form.customProperty);
		}
		var insertPos = form.insertPos;
		var n = "property";
		var nv = "propertyValue";
		if(fieldLabelHeader)
		  nv= fieldLabelHeader+"PropertyValue";
		
		var hasTemplate = false;
		for (var i = 1; i < 11; i++) {
			var s = n + i;
			if (jsonData.result[0][s]) {
				var field = new Ext.form.TextField({
					fieldLabel : this.breakWord(jsonData.result[0][s]),
					name : nv + i,
					propertyName : jsonData.result[0][s],
					value : pvalus[jsonData.result[0][s]]
							? pvalus[jsonData.result[0][s]]
							: "",
					maxLength : 25
				});
				var panel = new Ext.Panel(config);
				container.insert(insertPos++, panel);
				panel.add(field);
				form.form.add(field);
				hasTemplate = true;
			}
		}
		var q = new Ext.form.Hidden({
			name : !fieldLabelHeader?'quotetype':fieldLabelHeader+"Quotetype",
			value : quotetype
		});
		var t = new Ext.form.Hidden({
			name : !fieldLabelHeader?'templateItemId':fieldLabelHeader+"TemplateItemId"
		});
		var tp = new Ext.form.Hidden({
			name : !fieldLabelHeader?'templateId':fieldLabelHeader+"TemplateId",
			value : jsonData.result[0]["templateId"]
		});
		
		var hs = new Ext.form.Hidden({
			name : !fieldLabelHeader?'hasTemplate':fieldLabelHeader+"HasTemplate",
			value :hasTemplate
		});
		container.add(q);
		container.add(t);
		container.add(tp);
		container.add(hs);
		form.form.add(q);
		form.form.add(t);
		form.form.add(tp);
		form.form.add(hs);

		form.hasTemplate = hasTemplate;
		/*
		 * if(!hasTemplate) { return; }
		 */
		if (hasTemplate && container.hidden && !isOffline)
			container.show();
		container.doLayout();

		form.fireEvent('afterCustomlayout', form,quotetype);
	}

	/**
	 * 复制规则： 来源单没有模版，则不复制 有：目的单有对应的自定义项，则如果来源单的对应自定义项值覆盖，不管来源的是否为空
	 */
	this.copyTemplateItems = function(from, quoteId, quoteType) {
		if (typeof(isOffline) !== 'undefined') {
			// 离线没有自定义项
			if (isOffline == true)
				return;
		}
		if (!quoteId)
			return;
		Ext.Ajax.request({
			url : '/scmMng/template.do?method=getAllTemplateInfo',
			params : {
				quoteId : quoteId,
				quoteType : quoteType
			},
			success : function(result, request) {
				var jsonData = Ext.util.JSON.decode(result.responseText);
				var data = jsonData.result[0];
				if (data.hasTemplate == false)
					return;
				else {
					var args = {};
					var pfield = "property";
					var pvalue = "propertyValue";
					for (var i = 1; i < 11; i++) {
						if (data[pfield + i]) {
							args[data[pfield + i]] = data[pvalue + i];
						}
					}
					for (var i = 1; i < 11; i++) {

						if (from.form.findField(pvalue + i)) {
							//
							if (args[from.form.findField(pvalue + i).propertyName] !== undefined) {
								from.form
										.findField(pvalue + i)
										.setValue(args[from.form
												.findField(pvalue + i).propertyName]);
							}

						}
					}
					from.form.findField()
				}

			},
			failure : function(result, request) {

			}
		});
	}
	this.loadTemplateItems = function(form, flag) {
		if (typeof(isOffline) !== 'undefined') {
			// 离线没有自定义项
			if (isOffline == true) {
				this.fireEvent('load')
				return;
			}
		}

		var quoteId = form.quoteId;

		if (!form.hasTemplate || !quoteId) {
			this.fireEvent('load')
			return;
		}
		var reader = form.form.reader;
		Ext.apply(form.form, {
					reader : new Ext.data.JsonReader({
						// 所需数据的tagname
						root : 'result',
						fields : ["templateItemId", "quoteId",
								"propertyValue1", 'propertyValue2',
								"propertyValue3", "propertyValue4",
								"propertyValue5", "propertyValue6",
								"propertyValue7", "propertyValue8",
								"propertyValue9", "propertyValue10"]
					})
				});
		form.form.load({
			scope : this,
			url : '/scmMng/template.do?method=getTemplateItems',
			params : {
				quoteId : quoteId
			},
			success : function(bform, action) {
				Ext.apply(form.form, {
							reader : reader
						});
				if (flag == "copy" || flag == "Copy" || flag == "3") {
					if (bform.findField('templateItemId'))
						bform.findField('templateItemId').setValue('');
					if (bform.findField('quoteId'))
						bform.findField('quoteId').setValue('');
				}
				this.fireEvent('load')
				this.fireEvent('loaditemssuccess')
			},
			failure : function(result, request) {
				Ext.apply(form.form, {
							reader : reader
						});
				this.fireEvent('load')
				this.fireEvent('loaditemsfail')
			}
		});
	};
	
	this.loadProperty = function(form, quotetype, config, container,fieldLabelHeader) {
		var pageStatus = request("pageStatus");
		var editFlag = request("editFlag");
		var f;
		if (pageStatus && !editFlag)
			f = pageStatus;
		else if (!pageStatus && editFlag)
			f = editFlag;
		if (form.hasLoadTemplate) {
			this.loadTemplateItems(form, f);
			return;
		}
		var reader = form.form.reader;
		Ext.apply(form.form, {
					reader : new Ext.data.JsonReader({
						// 所需数据的tagname
						root : 'result',
						fields : [{
									name : 'quotetype',// 模板对应的引用对象
									type : 'string'
								}, "templateId", "property1", 'property2',
								"property3", "property4", "property5",
								"property6", "property7", "property8",
								"property9", "property10"]
					})
				});
		Ext.Ajax.request({
			scope : this,
			url : '/scmMng/template.do?method=loadProperty',
			params : {
				quotetype : quotetype
			},
			success : function(result, request) {
				Ext.apply(form.form, {
							reader : reader
						});
				form.hasLoadTemplate = true;
				if (typeof(isOffline) !== 'undefined') {
					// 离线没有自定义项
					if (isOffline == true) {
						this.fireEvent('load')
						return;
					}
				}
				// 没有数据
				var jsonData = Ext.util.JSON
						.decode(result.responseText);
				if (!jsonData.success) {
					form.hasTemplate = false;
					this.fireEvent('load')
					return;
				} else {
					if (!container)
						container = form;
					this.addItems(form, container, jsonData, config, quotetype,fieldLabelHeader);
				}
				this.loadTemplateItems(form, f);

			},
			failure : function(result, request) {
				Ext.apply(form.form, {
							reader : reader
						});
				form.hasLoadTemplate = true;
				form.hasTemplate = false;
				this.fireEvent('load');

			}
		});

	}
}
Ext.extend(CustomManager, Ext.util.Observable, {});
Ext.override(Ext.data.Record, {
			set : function(name, value) {
				if (String(this.data[name]) == String(value)) {
					return;
				}
				this.dirty = true;
				if (!this.modified) {
					this.modified = {};
					this.lastModified = '';
				}
				if (typeof this.modified[name] == 'undefined') {
					this.modified[name] = this.data[name];
				}
				this.lastModified = name;
				this.data[name] = value;
				if (!this.editing && this.store) {
					this.store.afterEdit(this);
				}
			}
		})

/*******************************************************************************
 * 统一把验证提示放在控件的下方
 ******************************************************************************/
Ext.override(Ext.form.Field, {
			msgTarget : "under",
			validate : function(isMsg) {
				if (this.disabled
						|| this.validateValue(this.processValue(this
										.getRawValue()), isMsg)) {
					this.clearInvalid();
					return true;
				}
				return false;
			}
		})

Ext.override(Ext.form.BasicForm, {
			isValid : function() {
				var valid = true;
				this.items.each(function(f) {
					if (!f.validate(true)) {
						valid = false;
					}
				});
				return valid;
			}
		})
/*******************************************************************************
 * 统一把验证提示放在控件的下方结束
 ******************************************************************************/
/*******************************************************************************
 * 对单据列表验证统一布局，orPanel:待验证的panel，containPanel为整体panel
 ******************************************************************************/
var formRepeatLayout = function(orPanel, containPanel) {
	orPanel.setSize(orPanel.getEl().getWidth(), orPanel.form.getEl().getHeight());
	containPanel.doLayout();
}

Ext.override(Ext.form.FormPanel, {
			initEvents : function() {
				Ext.FormPanel.superclass.initEvents.call(this);
				this.items.on('remove', this.onRemove, this);
				this.items.on('add', this.onAdd, this);
				if (this.monitorValid) { // initialize after render
					this.startMonitoring();
				}
				var formPanel = this;
				this.form.items.each(function() {
					if (!this.allowBlank) {
						this.on('valid', function() {
									if (this.errorEl) {
										formPanel.setSize(formPanel.getEl().getWidth(),
												formPanel.form.getEl().getHeight());
										formPanel.ownerCt.doLayout();
									}
								})
					}
				})
			}
		})
/*******************************************************************************
 * 对单据列表验证统一布局结束
 ******************************************************************************/

/*******************************************************************************
 * 常用查询
 ******************************************************************************/
/**
 * 所有自定项查询都要继承该类，并且把开始查询放到startSearch函数中 并且在config给出该自定项查询所在模块标志modelId
 * 
 */
Ufida.AbstractSearchWindow = function(config) {
	this.modelId = config.modelId;
	this.requestPath = config.requestPath;

	Ext.applyIf(config, {
				resizable : false,
				bodyStyle : 'padding:5px 5px 0px',
				width : 350,
				modal : true,
				autoHeight : true,
				buttonAlign : 'center',
				closeAction : 'hide',
				title : '自定义查询'
			});

	this.addEvents({
		saveSuccess : true
	});

	Ufida.AbstractSearchWindow.superclass.constructor.call(this, config);
}
Ext.extend(Ufida.AbstractSearchWindow, Ext.Window, {
			startSearch : function() {
			},
			addAsCommonSearch : function() {
				if (!this.addWindow) {
					this.addWindow = new Ufida.AddSearchWindow();
					this.addWindow.on('saveOk', this.process, this);
				}
				this.addWindow.show();
			},
			cancle : function() {
				this.fireEvent('cancel');
				this.hide();
			},
			/**
			 * 保存到后台 saveSuccess
			 */
			process : function(queryName) {
				var param = {};
				param.modelId = this.modelId;
				param.queryName = queryName;
				param.queryString = Ext.urlEncode(this.getParameters());

				var el = this.addWindow.searchForm.el;

				el.mask("正在保存数据......", 'x-mask-loading');
				Ext.Ajax.request({
					url : '/scmMng/commonQueryAction.do?method=saveCommonQuery',
					params : param,
					method : 'post',
					scope : this,
					success : function(result, request) {
						el.unmask();
						this.fireEvent('saveSuccess', this);
						this.addWindow.hide();
						messageloaded('保存常用查询成功!');
					},
					failure : function(result, request) {
						el.unmask();
						displayMessageBox('信息', '保存常用查询失败!');

					}
				});
			}
		});

Ufida.AddSearchWindow = function() {
	this.searchForm = new Ext.FormPanel({
		labelAlign : 'left',
		labelWidth : 85,
		border : false,
		frame : false,
		header : false,
		bodyStyle : 'padding:5px 5px 0px',
		maskDisabled : false,
		autoHeight : true,
		waitMsgTarget : true,
		items : [{
			layout : 'column',
			border : false,
			items : [{
				columnWidth : 1,
				border : false,
				layout : 'form',
				items : [{
							xtype : 'hidden',
							name : 'id'
						}, {
							xtype : 'textfield',
							fieldLabel : '<font color=red>*</font>常用查询名称',
							msgTarget : 'under',
							maxLength : 20,
							allowBlank : false,
							name : 'queryName',
							anchor : '100%'
						}]
			}]
		}]
	});

	Ufida.AddSearchWindow.superclass.constructor.call(this, {
				layout : 'fit',
				width : 400,
				autoHeight : true,
				closeAction : 'hide',
				items : this.searchForm,
				plain : true,
				title : '新增常用查询',
				buttonAlign : 'center',
				modal : true,
				buttons : [{
							id : 'save',
							text : '保存',
							disabled : false,
							scope : this,
							handler : function() {
								this.save();

							}
						}, {
							id : 'cancel',
							text : '取消',
							scope : this,
							handler : function() {
								this.hide();
							}
						}],
				listeners : {
					'beforeshow' : function() {
						this.searchForm.form.reset();
					},
					'show' : function() {
						var f = this.searchForm.form.findField('queryName');
						if (f && typeof f.focus == 'function') {
							f.focus.defer(100, f);
						}
					}
				}
			});

	this.addEvents({
		saveOk : true
	});

}

Ext.extend(Ufida.AddSearchWindow, Ext.Window, {
	save : function() {
		var queryName = this.searchForm.form.findField('queryName').getValue()
				.trim();
		if (!this.searchForm.form.isValid()) {
			return;
		}
		if (!queryName) {
			this.searchForm.form
					.findField('queryName')
					.markInvalid(this.searchForm.form.findField('queryName').blankText);
			return;
		}
		this.fireEvent('saveOk', queryName.trim());
	}
});
Ufida.CommonSearchPanel = function(config) {
	this.modelId = config.modelId;
	Ext.applyIf(config, {
				title : '常用查询',
				autoExpandColumn : 0,
				hideHeaders : true,
				border : false,
				autoScroll : true,
				loadMask : {
					msg : '正在加载数据......'
				},
				viewConfig : {
					forceFit : true
				}
			});
	this.columns = [{
				dataIndex : 'queryName',
				renderer : this.rendererSearch,
				width : 140,
				resizable : false
			}, {
				dataIndex : 'id',
				renderer : this.rendererop,
				resizable : false,
				align : 'right',
				width : 40
			}];

	this.reader = new Ext.data.JsonReader({
		root : 'result',
		fields : [{ name : 'id'
				},{ name : 'queryName'
				},{ name : 'accountbookId'
				},{ name : 'queryString'
				}]

	});
	this.store = new Ext.data.Store({
		autoLoad : true,
		// 使用一个URL获取数据源
		proxy : new Ext.data.HttpProxy({
			url : '/scmMng/commonQueryAction.do?method=queryList&modelId='
					+ this.modelId
		}),
		reader : this.reader
	});

	Ufida.CommonSearchPanel.superclass.constructor.call(this, config);
	this.on('cellclick', this.cellclick, this);

	this.addEvents({
		query : true
	});

};

Ext.extend(Ufida.CommonSearchPanel, Ext.grid.GridPanel, {
	rendererop : function(value, cellmeta, record, rowIndex, columnIndex, store) {
		if (record.get('accountbookId') == 'system') {
			return "";
		} else {
			return "<a href='javascript:void(0)' style='cursor: pointer' >删除</a> ";
		}
	},
	rendererSearch : function(value, cellmeta, record, rowIndex, columnIndex,
			store) {
		return "<span style= 'cursor:hand;font-size:12px;'>" + value+ "</span>";
	},
	removeRow : function(rowIndex) {
		var data = this.store.data;
		if (data.get(rowIndex).get('accountbookId') == 'system')
			return;
		Ext.MessageBox.confirm("提醒", "是否真的要删除所选的内容", function(button, text) {
					if (button == "yes") {
						param = {
							id : data.get(rowIndex).get('id')
						};
						Ext.Ajax.request({
							url : '/scmMng/commonQueryAction.do?method=deleteQuery',
							params : param,
							scope : this,
							method : 'post',
							success : function(result, request) {
								messageloaded('删除常用查询成功!');
								this.store.reload();
							},
							failure : function(result, request) {
								displayMessageBox('信息', '删除常用查询失败!');

							}
						});
					}
				}, this);

	},

	cellclick : function(grid, rowIndex, columnIndex, e) {
		// 查询
		if (columnIndex == 0) {
			var params = Ext.urlDecode(this.store.data.get(rowIndex).get('queryString'));
			this.fireEvent('query', params);
		}
		// 移除
		else if (columnIndex == 1) {
			this.removeRow(rowIndex);
		}
	}
});

/**
 * 列表的常用查询模板
 */
Ufida.AbstractListQueryPanel = function(config) {
	// update on 2009.06.01
	this.commonQueryPanel = new Ufida.CommonSearchPanel({
		region : 'center',
		modelId : config.modelId
	});
	// update on 2009.06.01 更新布局
	Ufida.AbstractListQueryPanel.superclass.constructor.call(this, {
				title : '请查询单据',
				bodyStyle : 'padding:2px 10px',
				layout : 'border',
				items : [{
							height : 150,
							region : 'north',
							border : false,
							layout : 'form',
							bodyStyle : 'padding:2px 10px',
							items : config.subItems
						}, this.commonQueryPanel]

			});
	this.addEvents({
		'query' : true,
		'customRetrieveQuery' : true
	});

	// update on 2009.06.01 添加事件处理
	this.commonQueryPanel.on('query', function(params) {
				this.fireEvent('query', params);
			}, this);
}
Ext.extend(Ufida.AbstractListQueryPanel, Ext.Panel, {
			// update on 2009.06.01
			loadCommonQuery : function() {
				this.commonQueryPanel.store.reload();
			}
		});
/**
 * 高级查询window
 * 
 */
Ufida.AdvancedQueryPanel = function(config) {
	Ext.applyIf(config, {
				labelWidth : 80,
				labelAlign : 'right',
				border : false,
				reader : new Ext.data.JsonReader({
					// 所需数据的tagname
					root : 'result',
					fields : [{
								name : 'quotetype'// 模板对应的引用对象
							}, "templateId", "property1", 'property2',
							"property3", "property4", "property5", "property6",
							"property7", "property8", "property9", "property10"]
				}),
				autoHeight : true,
				layout : 'column',
				defaults : {
					columnWidth : .5,
					border : false,
					autoHeight : true,
					layout : 'form',
					defaults : {
						xtype : 'textfield',
						anchor : '90%'
					}
				},
				items : this.formitems
			});
	Ufida.AdvancedQueryPanel.superclass.constructor.call(this, config);
}
Ext.extend(Ufida.AdvancedQueryPanel, Ext.form.FormPanel, {
			getParameters : function() {
				var params = this.form.getValues();
				params.billType = this.billType.getValue();
				if(params["startDate"]){
					params['startDate'] = stringFormatYMD(params['startDate']);
				}
				if(params['endDate']){
					params['endDate'] = stringFormatYMD(params['endDate']);
				}
				if (this.form.findField('period')) {
					params.period = this.form.findField('period').getValue();
					timeToPeriod(this.form.findField('period').getValue(),
							"startDate", "endDate", params);
				}
				if (this.form.findField('noclass')
						&& this.form.findField('noclass').getValue() == 'noclass') {
					params.classificationName = 'noclass';
					params.goodstypeName = 'noclass';
				}

				params.isAdvancedQuery = true;
				return params;
			},
			constructForm : function(formFields) {
				var ff = [];
				for (var i = 0; i < formFields.length; i++) {
					var subff = {};
					subff.items = [];
					subff.items[0] = formFields[i];
					ff[i] = subff;
				}
				return ff;
			}
		});
Ufida.AdvancedQueryWindow = function(config) {
	this.formPanel = config.formPanel;
	config.insertPos = config.formPanel.items.length;
	Ext.applyIf(config, {
				title : '高级查询',
				width : 600,
				items : this.formPanel,
				buttons : [{
							text : '开始查询',
							scope : this,
							handler : function() {
								var params = this.getParameters();
								this.fireEvent('query', params);
							}
						},{ // update on 2009.06.01
							text : '保存为常用查询',
							scope : this,
							handler : this.addAsCommonSearch
						}, {
							text : '取消',
							scope : this,
							handler : function() {
								this.fireEvent('cancel', self);
								this.hide();
							}
						}],
				listeners : {
					scope : this,
					'show' : function() {
						this.formPanel.form.reset();
						this.formPanel.fireEvent( 'statereset' );
					} 
				}
			});
	Ext.apply(this, config);
	Ufida.AdvancedQueryWindow.superclass.constructor.call(this, config);
	this.constructCustomProperty(config.hasCustomProperty, config.insertPos,config.customFlag);
	this.formPanel.addEvents({
		'statereset' : true
	})
};
Ext.extend(Ufida.AdvancedQueryWindow, Ufida.AbstractSearchWindow, {
	getParameters : function() {
		return this.formPanel.getParameters();
	},
	constructCustomProperty : function(hasCustomProperty, insertPos, customFlag) {
		if (hasCustomProperty) {
			this.formPanel.on('render', function() {
						this.formPanel.insertPos = insertPos;
						new CustomManager().loadProperty(this.formPanel,
								customFlag, {
									columnWidth : .5,
									layout : 'form',
									labelWidth : this.formPanel.labelWidth,
									labelAlign : this.formPanel.labelAlign,
									border : false,
									autoHeight : true,
									defaults : {
										anchor : '90%'
									}
								});
					}, this);
		}
	}
});
/**
 * 报表的常用查询模板，包含高级查询
 */
Ufida.AbstractReportQueryPanel = function(config) {
	Ext.apply(this, config);

	// update on 2009.06.04
	this.commonQueryPanel = new Ufida.CommonSearchPanel({
		region : 'center',
		border : true,
		hideHeaders : true,
		modelId : config.modelId
	});

	this.advancedLink = new Ufida.widgets.Link({
		value : '高级查询',
		fontSize : "13px;",
		linkStyle : 'widget-link-advanced',
		style : 'font-weight:bold;verticalAlign:middle;font-family:tahoma,arial,verdana,sans-serif',
		handler : function(v) {
			if (!this.advancedWindow) {
				this.advancedWindow = new Ufida.AdvancedQueryWindow({
					/*
					 * formFields : [{ fieldLabel : 'aa', name : 'aa' }, {
					 * fieldLabel : 'bb', name : 'bb' }],
					 */
					/*
					 * hasCustomProperty:true, customFlag:Ufida.ClientCustom,
					 */
					formPanel : config.formPanel,
					hasCustomProperty : config.hasCustomProperty,
					customFlag : config.customFlag,
					modelId : config.modelId
				});
				this.advancedWindow.on('query', function(params) {
							this.fireEvent('query', params);
						}, this);
				this.advancedWindow.on('saveSuccess', this.loadCommonQuery,
						this)
			}
			this.advancedWindow.show();
		},
		scope : this
	});
	// update on 2009.06.04 更新布局
	Ufida.AbstractReportQueryPanel.superclass.constructor.call(this, {
				layout : 'border',
				border : false,
				collapsible : true,
				title : '请选择查询条件',
				items : [{
					height : config.northHeight,
					region : 'north',
					border : false,
					layout : 'form',

					items : config.subItems,
					buttonAlign : 'left',
					buttons : [{
								text : '开始查询',
								scope : this,
								handler : function() {
									this.fireEvent("query", this
													.getParameters());
								}
							}, this.advancedLink]
				}, this.commonQueryPanel]

			});

	this.addEvents({
		'query' : true,
		'customRetrieveQuery' : true
	});

	// update on 2009.06.04 添加事件处理
	this.commonQueryPanel.on('query', function(params) {
				this.fireEvent('query', params);
			}, this);

}
Ext.extend(Ufida.AbstractReportQueryPanel, Ext.Panel, {
			// update on 2009.06.04
			loadCommonQuery : function() {
				this.commonQueryPanel.store.reload();
			}
		});

/**
 * 本月本季度 开始结束之间的关系处理 .如果开始日期和结束日期正好是本月本季度的开始和结束,那么根据本月本季度查询
 * 那么清空开始结束日期，以本月本季度作为查询条件
 * 
 */
function timeToPeriod(periodValue, startDate, endDate, params) {
	if (!params)
		return;
	if (periodValue) {
		if (periodValue == '本月') {
			if ((params[startDate] == showMonthFirstDay().format('Ymd'))
					&& (params[endDate] == showMonthLastDay().format('Ymd'))) {
				params[startDate] = "";
				params[endDate] = "";
			}
		}
		if (periodValue == '上月') {
			if ((params[startDate] == showPreviousFirstDay().format('Ymd'))
					&& (params[endDate] == showPreviousLastDay().format('Ymd'))) {
				params[startDate] = "";
				params[endDate] = "";
			}
		}
		if (periodValue == '本季度') {
			if ((params[startDate] == showFirstQuarterDay().format('Ymd'))
					&& (params[endDate] == showLastQuarterDay().format('Ymd'))) {
				params[startDate] = "";
				params[endDate] = "";
			}
		}
	}
}
/**
 * 把period转换成时间段
 */
function periodToTime(periodValue, startDate, endDate, params) {
	if (params) {
		if ((!params[startDate] && !params[endDate] && periodValue)) {
			if (periodValue == '本月') {
				params[startDate] = showMonthFirstDay().format('Ymd');
				params[endDate] = showMonthLastDay().format('Ymd');
			}
			if (periodValue == '上月') {
				params[startDate] = showPreviousFirstDay().format('Ymd');
				params[endDate] = showPreviousLastDay().format('Ymd');
			}
			if (periodValue == '本季度') {
				params[startDate] = showFirstQuarterDay().format('Ymd');
				params[endDate] = showLastQuarterDay().format('Ymd');
			}

		}
	}
}

/**
 * 2009-06-09 傲起 使store 开始加载时就采用分页，解决前台和后台中Limit的设置不同导致的加载页面错误
 */
Ext.override(Ext.PagingToolbar, {
			beforeLoad : function(){
		        if(this.rendered && this.loading){
		            this.loading.disable();
		        }
		        Ext.applyIf(this.store.baseParams, {
					limit : this.pageSize
				});
		    }
		});
/**
 * 2009.06.15 默认仓库、帐户和计量方案
 */
getDefaultData = function(type, callback) {
	return 0;
	Ext.Ajax.request({
		url : '/scmMng/commonQueryAction.do?method=getDefaultData',
		method : 'post',
		params : {
			tableName : type
		},
		scope : this,
		failure : function(result, request) {
			displayMessageBox("提示", "网络超时，请稍候再试！");

		},
		success : callback
	});
}
getDefaultStoreRoom = function(hid_storeroom, txt_storeroom) {
	var cbFn = function(result, request) {
		var jsonData = Ext.util.JSON.decode(result.responseText);
		var data = jsonData.result[0];
		// 不空，有默认值
		if (data != null)
			if (data.storeroomId) {
				hid_storeroom.setValue(data.storeroomCode);
				txt_storeroom.setValue(data.storeroomName);
			}
	};
	getDefaultData('StoreRoom', cbFn);
}
getDefaultBankAccount = function(payacc,queryPayAccountCurBalance) {
	var cbFn = function(result, request) {
		var jsonData = Ext.util.JSON.decode(result.responseText);
		var data = jsonData.result[0];
		// 不空，有默认值
		if (data.id) {
			payacc.setValue(data.accName);
			if(queryPayAccountCurBalance)
			  queryPayAccountCurBalance();
		}
		
	};
	getDefaultData('BankAccount', cbFn);
}
getDefaultMeasurement = function(hid_measurementPlan, txt_measurementPlan,
		hid_storePer, txt_storePer, hid_purPer, cb_purPer, hid_salePer,
		cb_salePer) {
	var cbFn = function(result, request) {
		var jsonData = Ext.util.JSON.decode(result.responseText);
		var data = jsonData.result[0];
		// 不空，有默认值
		if (data.measurementId) {
			
			hid_measurementPlan.setValue(data.measurementCode);
			txt_measurementPlan.setValue(data.measurementName);
 
			hid_storePer.setValue(data.basePerCode);
			txt_storePer.setValue(data.basePerName);

			hid_purPer.setValue(data.basePerCode);
			cb_purPer.setValue(data.basePerName);

			hid_salePer.setValue(data.basePerCode);
			cb_salePer.setValue(data.basePerName);
		}
	};
	getDefaultData('MeasurementItems', cbFn);
}
///**
// * 控制testField的输入字符，不能有 ‘,',<,>,&,〉,《,》,  delete by tongl 20091102
// */
//Ext.override(Ext.form.TextField, {
//			maskRe : /^[^'<&]+$/
//		});

Ufida.GridPanelWithDefault = function(config) {
	Ext.apply(this, config);
	Ufida.GridPanelWithDefault.superclass.constructor.call(this, config);
	this.on('cellclick', function(grid, rowIndex, columnIndex, e) {
				var record;
				if (grid.getColumnModel().getDataIndex(columnIndex) == 'isDefault') {
					record = grid.getStore().getAt(rowIndex);
					this.setDefault(record);
				}
			}, this);
}
Ext.extend(Ufida.GridPanelWithDefault, Ext.grid.GridPanel, {
	renderDefault : function(value) {
		if (value == 1)
			return '是\t\t'
					+ '<a href="javascript:void(0)" style="align::right;text-decoration: underline;">'
					+ '取消默认' + '</a>';
		else
			return '否\t\t'
					+ '<a href="javascript:void(0)" style="align:right;text-decoration: underline;">'
					+ '设为默认' + '</a>';
	},
	setDefault : function(record) {
		var f = record.get('isDefault');
		var id = record.get(this.getIdDataIndex());
		var param = {};
		param.id = id;
		param.tableName = this.getDefaultType();
		var msg = "";
		param.isDefault = f;
		// 是默认，则取消默认
		if (f == 1) {
			msg = "确定取消默认项么？";
		} else {
			msg = "确定设置为默认项么？";
		}
		Ext.MessageBox.confirm('提醒', msg, function(button, text) {
			if (button == "yes") {
				Ext.Ajax.request({
					url : '/scmMng/commonQueryAction.do?method=setDefaultDataTA',
					params : param,
					scope : this,
					method : 'post',
					success : function(result, request) {

						var jsonData = Ext.util.JSON
								.decode(result.responseText);
						if (jsonData) {
							if (jsonData.message == "hasDefault") {
								return displayMessageBox("提示", "已经有默认项！");
							} else {
								this.getStore().reload();
							}
						}
					},
					failure : function(result, request) {
						var jsonData = Ext.util.JSON
								.decode(result.responseText);
						if (jsonData) {
							if (jsonData.message == "hasDefault") {
								return displayMessageBox("提示", "已经有默认值！");
							}
						}
					}
				});
			}
		}, this);
	}
});

Ufida.output.Print = function(cm, ds, keyword, ary) {
	var all_data = [];
	Ext.Ajax.request({
		scope : this,
		url : ds.proxy.url,
		method : 'post',
		params : {
			limit : 999
		},
		failure : function(result, request) {
			displayMessageBox("提示", "单据检查失败");
		},
		success : function(result, request) {
			if (result.responseText) {
				var jsonData = Ext.util.JSON.decode(result.responseText);
				all_data = jsonData.result.result;
				ds = all_data;

				var noTotalFlag = false;
				if (!ary)
					ary = [];
				if (ary.length == 0) {
					noTotalFlag = true;
				}
				var tr = ''
				var header = ''
				var headerFlag = false;
				var totalAry = {}

				// 遍历行
				// for (var j = 0; j < ds.getCount(); j++) {
				for (var j = 0; j < ds.length; j++) {
					// var record = ds.getAt(j);
					var record = ds[j];
					var td = ''
					// 遍历列
					for (var i = 0; i < cm.getColumnCount(); i++) {
						var idx = cm.getDataIndex(i);
						var columnHeader = cm.getColumnHeader(i);
						var hiddenFlag = cm.isHidden(i);
						if (hiddenFlag) {
						} else {
							var content = '';
							if (idx) {
								// content = record.get(idx);
								content = record[idx];

								if (ary.indexOf(idx) != -1) {
									if (!totalAry[idx]) {
										totalAry[idx] = 0;
									}
									totalAry[idx] += content - 0;
								}
								
							var renderFunc = cm.getRenderer(i);
							var renderValue = renderFunc(content, null, record,
									j, i, ds);
							renderValue = Ext.util.Format
									.stripTags(renderValue);
							if (headerFlag) {
							} else {
								header += '<td align="right">' + columnHeader
										+ '</td>'
							}
							td += '<td align="right">'
									+ (renderValue || "&nbsp;") + '</td>';
							}else{
							}
						

						}
					}// end column

					headerFlag = true;
					tr += '<tr>' + td + '</tr>';
				}// end row

				var total_td = '';
				var total_tr = '';

				var first_tr_flag = true
				// 遍历合计列
				for (var i = 0; i < cm.getColumnCount(); i++) {
					var idx = cm.getDataIndex(i);
					var columnHeader = cm.getColumnHeader(i);
					var hiddenFlag = cm.isHidden(i);
					if (hiddenFlag) {
					} else {
						var content = totalAry[idx];
						var renderValue = '&nbsp;';
						// 当值为'0'时，js将其当作false处理。用 undefined 明确处理类型
						if (content !== undefined) {
							var renderFunc = cm.getRenderer(i);
							renderValue = renderFunc(content);
							renderValue = Ext.util.Format
									.stripTags(renderValue);
						} else {
						}

						if (first_tr_flag) {
							renderValue = '合计：' + renderValue;
							first_tr_flag = false;
						} else {
						}
						total_td += '<td align="right">'
								+ (renderValue || "&nbsp;") + '</td>';
					}
				}// end column

				total_tr = '<tr>' + total_td + '</tr>';

				header = '<tr>' + header + '</tr>';

				var title = '<div style="text-align:center;font-size: 24pt;font-weight: bold;width:100%;">'
						+ keyword + '</div><br>';
				var html = '';

				var printWidget;

				if (Ext.isIE) {
					printWidget = "<html><head> <META http-equiv='Content-Type' CONTENT='text/html; charset=utf-8'><OBJECT ID='jatoolsPrinter' CLASSID='CLSID:B43D3361-D975-4BE2-87FE-057188254255' codebase='/jatoolsPrinter.cab#version=4,2,0,0'></OBJECT>"
							+ "<script type='text/javascript'>"
							+ " function doPrint(how) { "
							+ " 	var myDoc = {   "
							+ '			fitToPage:true,'
							+ '			autoBreakPage:true,'
							+ '			autoBreakTable:{' 
							+ '              id:"mytable", '
							+ '              headerRows:1  '
							+ '         },'
							+ "  		settings : { "
							+ " 			orientation : 2,  "
							+ " 			leftMargin  : 90.5,  "
							+ " 			rightMargin : 90.5,  "
							+ " 			topMargin   : 90.5,  "
							+ " 			bottomMargin  : 90.5  "
							+ " 		}, "
							
							+ " 		header  : {height:20,html:'<div style=text-align:right;width:100%;>第 #p 页/共 #P 页</div>'},   "
							+ "			documents:document,  "
							+ "         copyrights : '杰创软件拥有版权 www.jatools.com'    "
							+ "		}; "
							+ " 	if (how == 'preview'){ jatoolsPrinter.printPreview(myDoc); } "
							+ " 	else{ jatoolsPrinter.print(myDoc, false); } "
							+ " }"
							+ "</script><style>tr{height:58}</style></head><body><DIV class='noprint' align=center>"
							+ "<INPUT onclick=javascript:doPrint() type=button value=打印 name=button_print />&nbsp;&nbsp;"
							+ "<INPUT onclick=javascript:doPrint('preview') type=button value=打印预览 name=button_show />"
							+ "</DIV></br>";

					if (noTotalFlag) {
						html = printWidget
								+ '<div id="page1" style="width:1027px">'
								+ title
								+ '<table id="mytable" border="1" align="center" cellpadding="0" cellspacing="0">'
								+ header + tr + '</table></div></body>'
								+ '</html>';
					} else {
						html = printWidget
								+ '<div id="page1" style="width:1027px">'
								+ title
								+ '<table  id="mytable" border="1" width="100%" align="center" cellpadding="0" cellspacing="0">'
								+ header + tr + total_tr
								+ '</table></div></body>' + '</html>';
					}
				} else {
					printWidget = "<html><head><META http-equiv='Content-Type' CONTENT='text/html; charset=utf-8'><style media='print'>.noprint{display:none;}</style></head><body><DIV class='noprint' align=center>"
							+ "<INPUT onclick=javascript:window.print(); type=button value='打印' />&nbsp;"
							+ "&nbsp;&nbsp;请点击浏览器“文件”菜单，选择“页面设置”和“打印预览”功能</DIV></br>";

					if (noTotalFlag) {
						html = printWidget
								+ title
								+ '<table border="1" align="center" cellpadding="0" cellspacing="0">'
								+ header + tr + '</table></body></html>';
					} else {
						html = printWidget
								+ title
								+ '<table border="1" width="100%" align="center" cellpadding="0" cellspacing="0">'
								+ header + tr + total_tr
								+ '</table></body></html>';
					}
				}

				stream(html);

			} else {
				alert('result.responseText')
			}
		}// success
	});
}

// 在新窗口显示打印报表
function stream(str) {
	var opner = new Ufida.WindowOpenFun();
	var win = opner.windowOpen("","newWin",'left=0,top=0,width='
							+ (screen.availWidth - 10) + ',height=' + (screen.availHeight - 55) + ',toolbar=no,menubar=yes,scrollbars=yes,status=yes,location=no');
	win.focus();
	win.document.open("text/html", "replace");
	win.document.write(str);
//	win.document.close();
		if(Ext.isIE8){
			setTimeout(function() {
				win.document.close();
			}, 1000);
		}else{
			setTimeout(function() {
				win.document.close();
			}, 500);
		}
}
 /**
 * 弹出提示框，点击确定后指定的field闪烁一次
 * @param {}  title
 * @param {}  msg
 * @param {}  field
 */
function alertAndHighlight(title, msg, field) {
	Ext.Msg.show({
		title : title,
		msg : msg,
		buttons : Ext.Msg.OK,
		icon : Ext.MessageBox.WARNING,
		fn : function() {
			if (field) {
				field.getEl().highlight();
			}
		},
		modal : true
	});
}

/** ie8 兼容 **/
if (Ext.isIE8) {
	// Ext.UseShims is wrong for IE8
	Ext.useShims = false;
	/**
	 * 解决Menu、DateMenu显示问题
	 */
	Ext.override(Ext.menu.Menu, {
		autoWidth : function() {
			var el = this.el, ul = this.ul;
			if (!el) {
				return;
			}
			var w = this.width;
			if (w) {
				el.setWidth(w);
			} else if (Ext.isIE && !Ext.isIE8) {
				el.setWidth(this.minWidth);
				var t = el.dom.offsetWidth; // force recalc
				el.setWidth(ul.getWidth() + el.getFrameWidth("lr"));
			}
		}
	});
	Ext.override(Ext.Element, {
		/**
		 * 解决ColumnLayout布局问题
		 */
		getViewSize : function() {
			var d = this.dom, doc = document, aw = 0, ah = 0;
			if (d == doc || d == doc.body) {
				return {width : Ext.lib.Dom.getViewWidth(),	height : Ext.lib.Dom.getViewHeight()};
			} else {
				return {
					width : d.clientWidth || d.offsetWidth,
					height : d.clientHeight || d.offsetHeight
				};
			}
		},
		/**
		 * 解决进货通宝撰写邮件报错的问题
		 */
		setStyle : function(prop, value){
	        if(typeof prop == "string" ){
	        	if( prop !='' ){
		            var camel = prop.replace(/(-[a-z])/gi, function(m, a){ return a.charAt(1).toUpperCase(); });
		            if(camel == 'opacity') {
		                this.setOpacity(value);
		            }else{
		                this.dom.style[camel] = value;
		            }
	        	}
	        }else{
	            for(var style in prop){
	                if(typeof prop[style] != "function" || prop[style]!='' ){
	                   this.setStyle(style, prop[style]);
	                }
	            }
	        }
	        return this;
	    }
	});
	/**
	 * 解决主页更新公告在ie8下无法滚动的问题
	 */
	Ext.onReady(function(){
		var marquees = window.document.getElementsByTagName('marquee') ;
		if( marquees && marquees.length>0 ){
			var marquee = marquees[0] ;
			var scrolldelay = marquee.getAttribute('scrolldelay')||100;
			var isPaused = false ;
			marquee.onmouseover = function(){
				isPaused = true ;
			}
			marquee.onmouseout = function(){
				isPaused = false ;
			}
			var scrollHeight = marquee.scrollHeight||0 ;
			var marqueeHeight = marquee.height||0 ;		
			var oldScrollTop = null ;
			function marqueeScroll(){
				if( isPaused === true){
					return ;
				} 
				oldScrollTop = marquee.scrollTop ;
				marquee.scrollTop += 1 ;
				if( oldScrollTop == marquee.scrollTop || marquee.scrollTop > (parseInt(scrollHeight)+parseInt(marqueeHeight))){
					marquee.scrollTop = 0 ;
				}
//				window.document.title = marquee.scrollTop +":"+":"+(parseInt(scrollHeight)+parseInt(marqueeHeight));
			}
			setInterval(marqueeScroll,scrolldelay);
		}
	});
}
/** ie8 兼容 End * */



 //start convert the string to date
function StringToDate(strVal){
	if(!strVal)
	   return "";
	else if (typeof strVal !== 'string')
	{
		return strVal.dateFormat('Y-m-d');
	}
	else if(strVal.length>8 || strVal.length<8)
		return strVal
	else{
        var myDate=new Date()
        myDate.setFullYear(strVal.substring(0,4),strVal.substring(4,6)-1,strVal.substring(6,8));
        myDate= myDate.dateFormat('Y-m-d');
		return myDate; 
	}
}
function  stringFormatYMD (str){
	 str=str.replace('-','');
     str=str.replace('-','');
     return str;
}
Ext.override(Ext.form.DateField,{
	altFormats : "Y-m-d",
    invalidText 	  : "{0} 是无效的日期,请按以下格式输入: {1}",
    disabledDaysText  : "禁用",
  	disabledDatesText : "禁用",
 	minText           : "该输入项的日期必须在 {0} 之后",
  	maxText           : "该输入项的日期必须在 {0} 之前",
  	format            : "y年m月d日",
    forceReadOnly : false,
    initComponent : function(){
        Ext.form.DateField.superclass.initComponent.call(this);
        if(typeof this.minValue == "string"){
            this.minValue = this.parseDate(this.minValue);
        }
        if(typeof this.maxValue == "string"){
            this.maxValue = this.parseDate(this.maxValue);
        }
        this.ddMatch = null;
        if(this.disabledDates){
            var dd = this.disabledDates;
            var re = "(?:";
            for(var i = 0; i < dd.length; i++){
                re += dd[i];
                if(i != dd.length-1) re += "|";
            }
            this.ddMatch = new RegExp(re + ")");
        }
        this.format='Y-m-d';
    },
    setValue : function(date){
    	date=StringToDate(date);
        Ext.form.DateField.superclass.setValue.call(this, this.formatDate(this.parseDate(date)));
        if(typeof date =='string'){
        	 this.value=stringFormatYMD(date);
        }
       else{
       	 this.value= date.dateFormat('Ymd');
       }
    },
    /**  DateField 设置为可以手工输入 */
	onRender : function(ct, position){
        Ext.form.DateField.superclass.onRender.call(this, ct, position);
        if( !this.el.up('.x-toolbar') ){
	        if( this.forceReadOnly === true ){
	            this.el.dom.readOnly = true;
	        }else{
	        	this.el.dom.readOnly = false;
	        }
        }
    },
    validateValue : function(value){
        value = this.formatDate(value);
        if(!Ext.form.DateField.superclass.validateValue.call(this, value)){
            return false;
        }
        if(value.length < 1){ // if it's blank and textfield didn't flag it then it's valid
             return true;
        }
        var svalue = value;
        value = this.parseDate(value);
        if(!value){
        	var demoDay = new Date();
        	demoDay.setFullYear(2009);demoDay.setMonth(8);demoDay.setDate(9);demoDay.setHours(9);demoDay.setMinutes(0);demoDay.setSeconds(0);demoDay.setMilliseconds(0);        	
            this.markInvalid(String.format(this.invalidText, svalue, demoDay.format(this.format)));
            return false;
        }
        var time = value.getTime();
        if(this.minValue && time < this.minValue.getTime()){
            this.markInvalid(String.format(this.minText, this.formatDate(this.minValue)));
            return false;
        }
        if(this.maxValue && time > this.maxValue.getTime()){
            this.markInvalid(String.format(this.maxText, this.formatDate(this.maxValue)));
            return false;
        }
        if(this.disabledDays){
            var day = value.getDay();
            for(var i = 0; i < this.disabledDays.length; i++) {
            	if(day === this.disabledDays[i]){
            	    this.markInvalid(this.disabledDaysText);
                    return false;
            	}
            }
        }
        var fvalue = this.formatDate(value);
        if(this.ddMatch && this.ddMatch.test(fvalue)){
            this.markInvalid(String.format(this.disabledDatesText, fvalue));
            return false;
        }
        return true;
    }
    
});
/**
 * 所有的需要并发检查的grid要继承该grid
 */ 
Ufida.CheckDataGridPanel = function(config){
	Ufida.CheckDataGridPanel.superclass.constructor.call( this,config);
}  
 Ext.extend(Ufida.CheckDataGridPanel,Ext.grid.GridPanel,{
 	checkData : function(callback) {
		var record = this.getSelectionModel().getSelected();
		Ext.Ajax.request({
			scope:this,
			url : '/scmMng/commonQueryAction.do?method=checkDataIfExist',
			method : 'post',
			params : {
				id : record.get(this.recordId),
				tableName:this.tableName
			},
			failure : function(result, request) {
				displayMessageBox("提示", "单据检查失败");
			},
			success : function(result, request) {
				if (result.responseText) {
					var jsonData = Ext.util.JSON.decode(result.responseText);
					if (!jsonData.success) {
						return displayMessageBox("提示", jsonData.message);
					}else{
						callback();
					}
				}else {
					callback();
				}
			}
		});
	}
 }); 
 
 /** 在线客服 **/
function getCookie(name)
{
	var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)");
	if(arr=document.cookie.match(reg)) return unescape(arr[2]);
	else return null;
}

function openDoyooCustomerChat(t) {
	//下面url地址是我们提供的及时语系统聊天接入地址，其中参数c的值需要修改成自己的公司ID
	var url = "http://chat.doyoo.net/WebModule/chat/p.do?c=18759&f=38879";
	//现在param中的参数n指客服ID，当指定这个参数后，Web CallCenter的系统会根据这个值接通到指定客服人员
	//这里的参数据可以修改为g，g指客服分组ID，当指定这个参数后，Web CallCenter的系统会根据这个值接通到指定客服分组
	//下面是接通到指定客服的代码
	//if( t!= null &&  t.length != 0 )
	// url +="&n=" + t;
	/*
	这里是分组模式接通代码，注：指定客服和分组方式不能同时使用。
	*/
	if( t!= null &&  t.length != 0 )
	url +="&g=" + t;
	var sid = getCookie("DOYOO_SESSION_ID");
	var cid = getCookie("DOYOO_USER_ID");
	if(sid!=null)
	url +="&v=" + sid;
	if(cid !=null)
	url +="&u=" + cid;
	var param = "height=460,width=690,directories=no," + "location=no,menubar=no," + "resizeable=no,status=no,toolbar=no,top=100,left=200";
	var opener= new Ufida.WindowOpenFun();
	 var opner =new Ufida.WindowOpenFun();
	var acceptWin =opner.windowOpen(url,"", param);	
	//注:此种方式不包含访客监测功能
}
/** 在线客服 END**/


/**
 * ***************************************************************************
 * EditorGrid 按回车键时进行焦点遍历
 * ***************************************************************************
 */
Ext.override(Ext.grid.CellSelectionModel,{
	onEditorKey : function(field, e){
		var k = e.getKey(), newCell, g = this.grid, ed = g.activeEditor;
        if(k == e.TAB){
            if(e.shiftKey){
                newCell = g.walkCells(ed.row, ed.col-1, -1, this.acceptsNav, this);
            }else{
                newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this);
            }
            e.stopEvent();
			ed.field.blur(); 
			if( typeof ed.field.triggerBlur =='function') {
				ed.field.triggerBlur();
			}
        }else if(k == e.ENTER){
            e.stopEvent();
            ed.completeEdit();
            if(e.shiftKey){
                newCell = g.walkCells(ed.row, ed.col-1, -1, this.acceptsNav, this);
            }else{
				newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this);
            }
			setTimeout(function(){
				ed.field.blur(); 
				if( typeof ed.field.triggerBlur =='function') {
					ed.field.triggerBlur();
				}
			},20);
        }else if(k == e.ESC){
        	e.stopEvent();
            ed.cancelEdit();
            
            //
            g.editing = false;
        	g.activeEditor = null;
        	g.getView().focusCell(ed.row, ed.col);
        }
        if(newCell){
            g.startEditing(newCell[0], newCell[1]);
        }
    }
});
Ext.override(Ext.grid.RowSelectionModel,{
	onEditorKey : function(field, e){
		var k = e.getKey(), newCell, g = this.grid, ed = g.activeEditor;
        if(k == e.TAB){
            if(e.shiftKey){
                newCell = g.walkCells(ed.row, ed.col-1, -1, this.acceptsNav, this);
            }else{
                newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this);
            }
            e.stopEvent();
			ed.field.blur(); 
			if( typeof ed.field.triggerBlur =='function') {
				ed.field.triggerBlur();
			}
        }else if(k == e.ENTER){
            e.stopEvent();
            ed.completeEdit();
            if(e.shiftKey){
                newCell = g.walkCells(ed.row, ed.col-1, -1, this.acceptsNav, this);
            }else{
				newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this);
            }
			setTimeout(function(){
				ed.field.blur(); 
				if( typeof ed.field.triggerBlur =='function') {
					ed.field.triggerBlur();
				}
			},20);
        }else if(k == e.ESC){
        	e.stopEvent();
            ed.cancelEdit();
        }
        if(newCell){
            g.startEditing(newCell[0], newCell[1]);
        }
    }
});
/**
 * ****************************************************************************
 * FormPanel 按回车键时进行焦点遍历
 * ****************************************************************************
 */
Ext.override(Ext.form.Field,{// 按回车时遍历
	focusTraversalKey 	: Ext.EventObject.ENTER,
	focusTraversalShift : false,
	focusTraversalCtrl 	: false,
	focusTraversalAlt  	: false
})
Ext.override(Ext.form.TextArea,{// textArea: 按 Ctrl+回车时遍历
	focusTraversalKey 	: Ext.EventObject.ENTER,
	focusTraversalCtrl 	: true
})
Ext.override(Ext.form.FormPanel,{
	initFocusTraversal : function(){
		var items = this.form.items ;
		function getNextFocusField(items,curIndex){
			var next = null ;
			for( var i=curIndex+1,len = items.getCount();i< len;i++){
				next = items.itemAt(i);
				// 找下一个field
				if( next.el && next.el.isVisible(true)&&
					next.el.dom &&next.el.dom.readOnly!==true ){
					break ;
				}
				next = null ;
			}
			return next ;
		}
		(function(){
	        items.each(function(c){
        		if( c.focusTraversalKeyMap ){
        			c.focusTraversalKeyMap.disable();
        		}
	        	if( c.isFormField && c.focusTraversalKey && Ext.get(c.id)){
	        		// 键盘映射
	        		c.focusTraversalKeyMap = new Ext.KeyMap(c.id, {
				        key	: c.focusTraversalKey,
				        shift: c.focusTraversalShift,
				        ctrl : c.focusTraversalCtrl,
				        alt : c.focusTraversalAlt,
				        fn	: function(key,e){
				            var current = this;
			            	var index = items.indexOf(current);
			            	var next = getNextFocusField(items,index);// 找下一个焦点遍历
			            	if( next ){
				            	current.blur();
				            	if( typeof current.triggerBlur=='function'){
				            		 current.triggerBlur();
				            	}
			            		next.focus();
			            	}
				        },
				        scope : c
				    });
	        	}
	        });
        }).defer(100);
	},
	initComponent :function(){
        this.form = this.createForm();
        Ext.FormPanel.superclass.initComponent.call(this);
        this.addEvents('clientvalidation');
        this.relayEvents(this.form, ['beforeaction', 'actionfailed', 'actioncomplete']);
        this.on('afterlayout',this.initFocusTraversal)
    }
});
/**
 * ************************************************
 * 全键盘输入,工具栏、按钮加速键AccKey  BEGIN
 * ************************************************
 */
Ext.override(Ext.Button,{
	onRender : function(ct, position){
        if(!this.template){
            if(!Ext.Button.buttonTemplate){
                // hideous table template
                Ext.Button.buttonTemplate = new Ext.Template(
                    '<table border="0" cellpadding="0" cellspacing="0" class="x-btn-wrap"><tbody><tr>',
                    '<td class="x-btn-left"><i>&#160;</i></td><td class="x-btn-center"><em unselectable="on"><button class="x-btn-text" type="{1}">{0}</button></em></td><td class="x-btn-right"><i>&#160;</i></td>',
                    "</tr></tbody></table>");
            }
            this.template = Ext.Button.buttonTemplate;
        }
        var btn, targs = [this.text || '&#160;', this.type];
        if(position){
            btn = this.template.insertBefore(position, targs, true);
        }else{
            btn = this.template.append(ct, targs, true);
        }
        var btnEl = btn.child(this.buttonSelector);
        btnEl.on('focus', this.onFocus, this);
        btnEl.on('blur', this.onBlur, this);
        this.initButtonEl(btn, btnEl);
        if(this.menu){
            this.el.child(this.menuClassTarget).addClass("x-btn-with-menu");
        }
        Ext.ButtonToggleMgr.register(this);
        
        // handle accKey 
        if( this.accKey ){
        	var accKey = this.accKey ;
        	var handler = this.onClick ;
        	if( !AccKey.getKeyMap(accKey) ){
	        	var key = accKey.replace(/(Ctrl|Shift|Alt)/ig,'').replace(/\+*/g,'');
	    		this.accKeyMap = new Ext.KeyMap(Ext.getDoc(), {
			        key	 : key,
			        stopEvent : true,
			        shift: accKey.contains('Shift'),
			        ctrl : accKey.contains('Ctrl'),
			        alt  : accKey.contains('Alt'),
			        fn	 : function(k,e){
			        	if( !this.disabled && this.handler ){
			        		e.button = 0
				        	this.handler.call(this.scope||this,e);
			        	}
			        },
			        scope : this
			    });
			    this.accKeyMap.stopEvent = true ;
			    AccKey.register(accKey,this.accKeyMap);
        	}
		    this.el.dom.setAttribute('title',((this.text||'')+' ')+accKey)
//		    this.el.dom.setAttribute('qclass','x-ufida-tip')
        }
    }
});
Ext.override(Ext.Toolbar.TextItem,{
    accKeyRe : /.*accKey\s*=\s*(?:['"])(\S*)(?:['"]).*/i,
    getEventHolder : function(){
    	var childs = this.el.childNodes ;
    	for( var i =0,len = childs.length; i<len ; i++){
    		if( typeof childs[i].onclick == 'function'){
    			return childs[i] ;
    		}
    	}
    },
	render : function(td){
        this.td = td;
        td.appendChild(this.el);
        var html = this.el.innerHTML ;
        if( this.accKeyRe.test(html) ){
	        var accKey = html.replace(this.accKeyRe,'$1')
	        if(accKey){
	        	var key = accKey.replace(/(Ctrl|Shift|Alt)/ig,'').replace(/\+*/g,'');
	        	var holder = this.getEventHolder(); 
	        	if( holder ){
		        	var handler = holder.onclick ;
		        	var item = this.el ;
	        		this.accKeyMap = new Ext.KeyMap(Ext.getDoc(), {
				        key	 : key,
				        stopEvent : true,
				        shift: accKey.contains('Shift'),
				        ctrl : accKey.contains('Ctrl'),
				        alt  : accKey.contains('Alt'),
				        fn	 : function(){
				        	if( !item.disabled ){
					        	handler.call(this.scope||this);
				        	}
				        }
				    });
				    this.accKeyMap.stopEvent = true ;
				    holder.setAttribute('ext:qtip',((holder.innerHTML||'')+'<br/>')+accKey)
				    holder.setAttribute('qclass','x-ufida-tip')
	        	}
	        }
        }
    }
});
Ext.KeyMap.prototype.addBinding = function(config){
    if(Ext.isArray(config)){
        for(var i = 0, len = config.length; i < len; i++){
            this.addBinding(config[i]);
        }
        return;
    }
    var keyCode = config.key, shift = config.shift, ctrl = config.ctrl,alt = config.alt,
        fn = config.fn || config.handler,
        scope = config.scope;
	if (config.stopEvent) {
	    this.stopEvent = config.stopEvent;    
	}	
    if(typeof keyCode == "string"){
        var ks = [];
        var keyString = keyCode.toUpperCase();
        for(var j = 0, len = keyString.length; j < len; j++){
            ks.push(keyString.charCodeAt(j));
        }
        keyCode = ks;
    }
    var keyArray = Ext.isArray(keyCode);
    var handler = function(e){
    	// 强制按键必须完全一致
    	//	eg:shift为false,则不能按下shift, Ext默认不考虑shift是否按下		--tongl 20091020
        if((shift?(e.shiftKey):!e.shiftKey) && (ctrl?(e.ctrlKey):!e.ctrlKey) &&  (alt?(e.altKey):!e.altKey)){
            var k = e.getKey();
            if(keyArray){
                for(var i = 0, len = keyCode.length; i < len; i++){
                    if(keyCode[i] == k){
                      if(this.stopEvent){
                          e.stopEvent();
                      }
                      fn.call(scope || window, k, e);
                      return;
                    }
                }
            }else{
                if(k == keyCode){
                    if(this.stopEvent){
                       e.stopEvent();
                    }
                    fn.call(scope || window, k, e);
                }
            }
        }
    };
    this.bindings.push(handler);
}

Ext.override(Ext.Editor,{
	onRender : function(ct, position){
	        this.el = new Ext.Layer({
	            shadow: this.shadow,
	            cls: "x-editor",
	            parentEl : ct,
	            shim : this.shim,
	            shadowOffset:4,
	            id: this.id,
	            constrain: this.constrain
	        });
	        this.el.setStyle("overflow", Ext.isGecko ? "auto" : "hidden");
	        if(this.field.msgTarget != 'title'){
	            this.field.msgTarget = 'qtip';
	        }
	        this.field.inEditor = true;
	        this.field.render(this.el);
	        if(Ext.isGecko){
	            this.field.el.dom.setAttribute('autocomplete', 'off');
	        }
	        this.field.on("specialkey", this.onSpecialKey, this);
	        if(this.swallowKeys){
	            this.field.el.swallowEvent(['keydown','keypress'],true);// preventDefault : true
	        }
	        this.field.show();
	        this.field.on("blur", this.onBlur, this);
	        if(this.field.grow){
	            this.field.on("autosize", this.el.sync,  this.el, {delay:1});
	        }
	    }
});
Ext.override(Ext.Element,{
	swallowEvent : function(eventName, preventDefault){
        var fn = function(e){
            e.stopPropagation();
            if(preventDefault && e.ctrlKey){
                e.preventDefault();
            }
        };
        if(Ext.isArray(eventName)){
            for(var i = 0, len = eventName.length; i < len; i++){
                 this.on(eventName[i], fn);
            }
            return this;
        }
        this.on(eventName, fn);
        return this;
    }
});
/**
 * **********************************************************
 * 全键盘输入,工具栏按钮加速键AccKey END
 * **********************************************************
 */
//

Ufida.WindowOpenFun = function(){}
Ext.extend(Ufida.WindowOpenFun, Ext.util.Observable, {
	windowOpenTemplate : function() {
		return this.windowOpen('/scmMng/base/scmUpload.xls',null,null, 'scmUpload.xls');
	},
	windowOpen : function(url, name, features , fileName) {
		return window.open(url, name, features);
	},
	windowOpenError:function(filename){
	  return this.windowOpen('/upload/'+ filename,null,null,filename);
    },
    windowExport:function(){
    	return this.windowOpen('/export/' + filename,null,null,filename);
    }
});

/**
 * ******************************************************************************
 * 更正Ext的bug：在FF等浏览器中,GridPanel中设置forceFit为true时,grid的最后一列宽度太小。
 * ******************************************************************************
 */
Ext.override(Ext.grid.GridView,{
	fitColumns : function(preventRefresh, onlyExpand, omitColumn){
        var cm = this.cm, leftOver, dist, i;
        var tw = cm.getTotalWidth(false);
        var aw = this.grid.getGridEl().getWidth(true)-this.scrollOffset;
        if(aw < 20){ // not initialized, so don't screw up the default widths
            return;
        }
        var extra = aw - tw;
        if(extra === 0){
            return false;
        }
        var vc = cm.getColumnCount(true);
        var ac = vc-(typeof omitColumn == 'number' ? 1 : 0);
        if(ac === 0){
            ac = 1;
            omitColumn = undefined;
        }
        var colCount = cm.getColumnCount();
        var cols = [];
        var extraCol = 0;
        var width = 0;
        var w;
        for (i = 0; i < colCount; i++){
            if(!cm.isHidden(i) && !cm.isFixed(i) && i !== omitColumn){
                w = cm.getColumnWidth(i);
                cols.push(i);
                extraCol = i;
                cols.push(w);
                width += w;
            }
        }
        var frac = (aw - cm.getTotalWidth())/width;
        while (cols.length){
            w = cols.pop();
            i = cols.pop();
            cm.setColumnWidth(i, Math.max(this.grid.minColumnWidth, Math.floor(w + w*frac)), true);
        }
//        if((tw = cm.getTotalWidth(false)) > aw){
//            var adjustCol = ac != vc ? omitColumn : extraCol;
//             cm.setColumnWidth(adjustCol, Math.max(1,
//                     cm.getColumnWidth(adjustCol)- (tw-aw)), true);
//        }
        if(preventRefresh !== true){
            this.updateAllColumnWidths();
        }
        return true;
    }
});

/**
 * ******************************************************************************
 * 更正Ext的bug:grid的最后一列宽度太小。 END
 * ******************************************************************************
 */
Ext.override(Ext.data.Store,{
	loadRecords : function(o, options, success){
        if(!o || success === false){
            if(success !== false){
                this.fireEvent("load", this, [], options);
            }
            if(options.callback){
                options.callback.call(options.scope || this, [], options, false);
            }
            return;
        }
        var r = o.records, t = o.totalRecords || r.length;
        if(!options || options.add !== true){
            if(this.pruneModifiedRecords){
                this.modified = [];
            }
            for(var i = 0, len = r.length; i < len; i++){
                r[i].join(this);
            }
            if(this.snapshot){
                this.data = this.snapshot;
                delete this.snapshot;
            }
            this.data.clear();
            this.data.addAll(r);
            this.totalLength = t;
            this.applySort();
            
            // grouping 
	        if(this.groupBy){
	        	this.sortData( Ext.isArray(this.groupBy) ? this.groupBy[0] : this.groupBy);
	        	var groupRcdsArr = [] ;
	        	var arr = [] ;
	        	var lastRcd = null ;
	        	for(var i=0,len = this.getCount();i<len;i++){
	        		var rcd = this.getAt(i) ;
					if( i == 0){
						arr = [rcd] ;
						continue ;
					}
					var lastRcd = this.getAt(i-1)
					if( this.isSameGroup(lastRcd, rcd)){
						arr.push(rcd);
					}else{
						groupRcdsArr.push(arr);
						arr = [rcd] ;
					}
	        	}
				if( arr.length > 0){
					groupRcdsArr.push(arr);
				}
				
				// 生成groupRecord
				var groupRcds = [] ;
				var uniqueArray = [] ;
				for(var i=0,len=groupRcdsArr.length;i<len; i++){
					var groupRcd = new Ufida.data.GroupRecord(groupRcdsArr[i][0]);
					var members = [] ;
					for( var j=0,length=groupRcdsArr[i].length;j<length;j++){
						members.push( groupRcdsArr[i][j].data );
					}
					groupRcd.groupMembers = members ;
					groupRcd.groupBy = this.groupBy ;
					if( this.uniqueField ){
						var uniqueValue = groupRcd.get(this.uniqueField) ;
						if( uniqueArray.contains(uniqueValue) ){
							var uniqueMbIndex = groupRcd.getUniqueMbIndex(uniqueArray,this.uniqueField) ;
							if(uniqueMbIndex !== undefined ){
								groupRcd.setActiveMember(uniqueMbIndex);
								uniqueArray.push(groupRcd.get(this.uniqueField))
							}else{
								groupRcd.setNoActiveMember();
							}
						}else{
							uniqueArray.push(uniqueValue)
						}
					}
					groupRcd.store = this ; // 'store' must be assigned at last
					groupRcds.push(groupRcd);
				}
				delete uniqueArray ;
				this.data.clear();
	            this.data.addAll(groupRcds);
	            this.totalLength = groupRcds.length;
	            this.applySort();
	        }
            this.fireEvent("datachanged", this);
        }else{
            this.totalLength = Math.max(t, this.data.length+r.length);
            this.add(r);
        }
        this.fireEvent("load", this, r, options);
        if(options.callback){
            options.callback.call(options.scope || this, r, options, true);
        }
    },
    isSameGroup 	: function(r1,r2){
		var groupBy = Ext.isArray(this.groupBy)? this.groupBy : [this.groupBy]
		for( var i=0,len=groupBy.length;i<len;i++){
			if( r1.get(groupBy[i]) != r2.get(groupBy[i]) ){
				return false ;
			}
		}
		return true ;
	}
});

Ufida.data.GroupRecord =function(record,id){
    Ufida.data.GroupRecord.superclass.constructor.call(this,Ext.apply({},record.data),id )
    Ext.applyIf(this,record);
    this.store = null ;
};
Ext.extend(Ufida.data.GroupRecord,Ext.data.Record,{
	groupBy 		: null,
	activeMbIndex	: 0 ,
	groupMembers	: [],
	addMember   	: function(obj){
		this.groupMembers.push(obj);
	},
	setActiveMember : function(index){
		if( this.groupMembers.length < index){
			throw {message:'indexOutOfBounds'};
		}
		this.activeMbIndex = index-0 ;
		Ext.apply(this.data,this.groupMembers[this.activeMbIndex]);
		if( this.store ){
			this.store.afterEdit(this);
		}
	},
	setNoActiveMember : function(){
		this.activeMbIndex = -1 ;
		var groupBy = Ext.isArray(this.groupBy)? this.groupBy : [this.groupBy] ;
		this.fields.each(function(field){
			if( !groupBy.contains(field.name) ){
				this.data[field.name] = '' ;
			}
		},this);
		if( this.store){
			this.store.afterEdit(this);
		}
	},
	getUniqueMbIndex : function(uniqueArray,uniqueField){
		for( var i=0,len=this.groupMembers.length;i<len;i++){
			if( !uniqueArray.contains(this.groupMembers[i][uniqueField])){
				return i ;
			}
		}
	}
});

/**
 * *********************************************************************
 * 升级 Ext3.0  BEGIN
 * *********************************************************************
 */
if(Ext.version.startsWith('3.0')){
	var El = Ext.Element;	
	function createXhrObject() {  
        var http;  
        var activeX = ['MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP', 'Microsoft.XMLHTTP'];  
  
        try {  
            http = new XMLHttpRequest();  
        } catch (e) {  
            for (var i = 0; i < activeX.length; ++i) {  
                try {  
                    http = new ActiveXObject(activeX[i]);  
                    break;  
                } catch (e) { }  
            }  
        } finally {  
            return http;  
        }  
    };
    Ext.apply(Ext.lib.Ajax,{
    	getConnectionObject : function(){
    		return {
    			conn : createXhrObject()
    		}
    	}
    })
	Ext.override(Ufida.TnPagingToolbar, {
		onLoad : function(store, r, o) {
			if (!this.rendered) {
				this.dsLoaded = [store, r, o];
				return;
			}
			this.cursor = o.params ? o.params[this.getParams().start] : 0;
			this.fireEvent('change', this, this.getPageData());
			this.renderBody();
		}
	})
	Ext.override(Ext.PagingToolbar, {
		onLoad : function(store, r, o) {
			if(!this.rendered){
	            this.dsLoaded = [store, r, o];
	            return;
	        }
	        var p = this.getParams();
	        this.cursor = (o.params && o.params[p.start]) ? o.params[p.start] : 0;
	        var d = this.getPageData(), ap = d.activePage, ps = d.pages;
	
	        this.afterTextItem.setText(String.format(this.afterPageText, d.pages));
	        this.inputItem.setValue(ap);
	        this.first.setDisabled(ap == 1);
	        this.prev.setDisabled(ap == 1);
	        this.next.setDisabled(ap == ps);
	        this.last.setDisabled(ap == ps);
	        this.refresh.enable();
	        this.updateInfo();
	        this.fireEvent('change', this, d);
			
		}
	})
	
	Ext.override(Ext.Toolbar,{
		getEl	: function(){
			return this.el ;
		}
	})
	
//	Ext.override(Ext.LoadMask,{
//		onLoad : function(){
//     	   this.el.unmask(true);
//    	}
//	})
	Ext.override(Ext.Element,{
		mask : function(msg, msgCls){
		    var me = this,
		    	dom = me.dom,
		    	dh = Ext.DomHelper,
		    	EXTELMASKMSG = "ext-el-mask-msg",
                el,
                data = Ext.Element.data,
                XMASKED = "x-masked",
				XMASKEDRELATIVE = "x-masked-relative",
                mask;
		    	
	        if(me.getStyle("position") == "static"){
	            me.addClass(XMASKEDRELATIVE);
	        }
	        if((el = data(dom, 'maskMsg'))){
	            el.remove();
	        }
	        if((el = data(dom, 'mask'))){
	            el.remove();
	        }
	
            mask = dh.append(dom, {cls : "ext-el-mask"}, true);
	        data(dom, 'mask', mask);
	
	        me.addClass(XMASKED);
	        mask.setDisplayed(true);
	        if(typeof msg == 'string'){
                var mm = dh.append(dom, {cls : EXTELMASKMSG, cn:{tag:'div'}}, true);
                data(dom, 'maskMsg', mm);
	            mm.dom.className = msgCls ? EXTELMASKMSG + " " + msgCls : EXTELMASKMSG + " x-mask-loading";
	            mm.dom.firstChild.innerHTML = msg;
	            mm.setDisplayed(true);
	            mm.center(me);
	        }
	        if(Ext.isIE && !(Ext.isIE7 && Ext.isStrict) && me.getStyle('height') == 'auto'){ // ie will not expand full height automatically
	            mask.setSize(undefined, me.getHeight());
	        }
	        return mask;
	    }
	})
	
	Ext.override(Ufida.TnPanel,{
		onRender : function(ct, position){
	        Ext.Panel.superclass.onRender.call(this, ct, position);
	        // 实现圆角样式增加四个element
			this.elements += ',outerBorder,innerBorder,outerBorderBottom,innerBorderBottom';
	        this.createClasses();
	        var el = this.el,
	            d = el.dom,
	            bw;
	        el.addClass(this.baseCls);
	        if(d.firstChild){ // existing markup
	            this.header = el.down('.'+this.headerCls);
	            this.bwrap = el.down('.'+this.bwrapCls);
	            var cp = this.bwrap ? this.bwrap : el;
	            this.tbar = cp.down('.'+this.tbarCls);
	            this.body = cp.down('.'+this.bodyCls);
	            this.bbar = cp.down('.'+this.bbarCls);
	            this.footer = cp.down('.'+this.footerCls);
	            this.fromMarkup = true;
	        }
	        if (this.preventBodyReset === true) {
	            el.addClass('x-panel-reset');
	        }
	        if(this.cls){
	            el.addClass(this.cls);
	        }
	
	        if(this.buttons){
	            this.elements += ',footer';
	        }
	
	        // This block allows for maximum flexibility and performance when using existing markup
	
	        // framing requires special markup
	        if(this.frame){
	            el.insertHtml('afterBegin', String.format(Ext.Element.boxMarkup, this.baseCls));
				
	            this.createElement('outerBorder',d.firstChild.firstChild.firstChild);
				this.createElement('innerBorder', d);
	            
	            this.createElement('header', d);
	            this.createElement('bwrap', d);
	
	            // append the mid and bottom frame to the bwrap
	            bw = this.bwrap.dom;
	            var ml = d.childNodes[1], bl = d.childNodes[2];
	            bw.appendChild(ml);
	            bw.appendChild(bl);
	
	            var mc = bw.firstChild.firstChild.firstChild;
	            this.createElement('tbar', mc);
	            this.createElement('body', mc);
	            this.createElement('bbar', mc);
	            this.createElement('footer', bw.lastChild.firstChild.firstChild);
	
	            this.createElement('innerBorderBottom', d);
				this.createElement('outerBorderBottom', d);
	            if(!this.footer){
	                this.bwrap.dom.lastChild.className += ' x-panel-nofooter';
	            }
	        }else{
	        	this.createElement('outerBorder',d);
				this.createElement('innerBorder', d);
	            this.createElement('header', d);
	            this.createElement('bwrap', d);
	
	            // append the mid and bottom frame to the bwrap
	            bw = this.bwrap.dom;
	            this.createElement('tbar', bw);
	            this.createElement('body', bw);
	            this.createElement('bbar', bw);
	            this.createElement('footer', bw);
				
	            this.createElement('innerBorderBottom', d);
				this.createElement('outerBorderBottom', d);
	            if(!this.header){
	                this.body.addClass(this.bodyCls + '-noheader');
	                if(this.tbar){
	                    this.tbar.addClass(this.tbarCls + '-noheader');
	                }
	            }
	        }
	
	        if(this.padding !== undefined) {
	            this.body.setStyle('padding', this.body.addUnits(this.padding));
	        }
	
	        if(this.border === false){
	            this.el.addClass(this.baseCls + '-noborder');
	            this.body.addClass(this.bodyCls + '-noborder');
	            if(this.header){
	                this.header.addClass(this.headerCls + '-noborder');
	            }
	            if(this.footer){
	                this.footer.addClass(this.footerCls + '-noborder');
	            }
	            if(this.tbar){
	                this.tbar.addClass(this.tbarCls + '-noborder');
	            }
	            if(this.bbar){
	                this.bbar.addClass(this.bbarCls + '-noborder');
	            }
	        }
	
	        if(this.bodyBorder === false){
	           this.body.addClass(this.bodyCls + '-noborder');
	        }
	
	        this.bwrap.enableDisplayMode('block');
	        
	        if(this.header){
	            this.header.unselectable();
	
	            // for tools, we need to wrap any existing header markup
	            if(this.headerAsText){
	                this.header.dom.innerHTML =
	                    '<span class="' + this.headerTextCls + '">'+this.header.dom.innerHTML+'</span>';
	
	                if(this.iconCls){
	                    this.setIconClass(this.iconCls);
	                }
	            }
	        }
	
	        if(this.floating){
	            this.makeFloating(this.floating);
	        }
	
	        if(this.collapsible){
	            this.tools = this.tools ? this.tools.slice(0) : [];
	            if(!this.hideCollapseTool){
	                this.tools[this.collapseFirst?'unshift':'push']({
	                    id: 'toggle',
	                    handler : this.toggleCollapse,
	                    scope: this
	                });
	            }
	            if(this.titleCollapse && this.header){
	                this.mon(this.header, 'click', this.toggleCollapse, this);
	                this.header.setStyle('cursor', 'pointer');
	            }
	        }
	        if(this.tools){
	            var ts = this.tools;
	            this.tools = {};
	            this.addTool.apply(this, ts);
	        }else{
	            this.tools = {};
	        }
	
	        if(this.buttons && this.buttons.length > 0){
	            this.fbar = new Ext.Toolbar({
	                items: this.buttons,
	                toolbarCls: 'x-panel-fbar'
	            });
	        }
	        this.toolbars = [];
	        if(this.fbar){
	            this.fbar = Ext.create(this.fbar, 'toolbar');
	            this.fbar.enableOverflow = false;
	            if(this.fbar.items){
	                this.fbar.items.each(function(c){
	                    c.minWidth = c.minWidth || this.minButtonWidth;
	                }, this);
	            }
	            this.fbar.toolbarCls = 'x-panel-fbar';
	
	            var bct = this.footer.createChild({cls: 'x-panel-btns x-panel-btns-'+this.buttonAlign});
	            this.fbar.ownerCt = this;
	            this.fbar.render(bct);
	            bct.createChild({cls:'x-clear'});
	            this.toolbars.push(this.fbar);
	        }
	
	        if(this.tbar && this.topToolbar){
	            if(Ext.isArray(this.topToolbar)){
	                this.topToolbar = new Ext.Toolbar(this.topToolbar);
	            }else if(!this.topToolbar.events){
	                this.topToolbar = Ext.create(this.topToolbar, 'toolbar');
	            }
	            this.topToolbar.ownerCt = this;
	            this.topToolbar.render(this.tbar);
	            this.toolbars.push(this.topToolbar);
	        }
	        if(this.bbar && this.bottomToolbar){
	            if(Ext.isArray(this.bottomToolbar)){
	                this.bottomToolbar = new Ext.Toolbar(this.bottomToolbar);
	            }else if(!this.bottomToolbar.events){
	                this.bottomToolbar = Ext.create(this.bottomToolbar, 'toolbar');
	            }
	            this.bottomToolbar.ownerCt = this;
	            this.bottomToolbar.render(this.bbar);
	            this.toolbars.push(this.bottomToolbar);
	        }
	        Ext.each(this.toolbars, function(tb){
	            tb.on({
	                scope: this,
	                afterlayout: this.syncHeight,
	                remove: this.syncHeight
	            });
	        }, this);
	        
	        
	         // 自动设置Panel高度
			if (this.body && this.autoHeight && this.minBodyHeight) {
				this.body.setStyle({
					'min-height' : this.minBodyHeight + this.body.defaultUnit,
					'height' : this.minBodyHeight + this.body.defaultUnit
				});
			}
	
			if (this.header) {
				this.header.addClass(this.headerIconCls || 'tnPanel-default-header');
			}
			// 设置面板样式
			this.setPanelStyle(this.colorName || this.defaultColorName);
	        
	        
	    }
	});
	Ext.override(Ext.PagingToolbarExt,{
		 onRender : function(ct,position){
			Ext.PagingToolbar.superclass.onRender.call(this,ct,position);
		 },
		 initComponent : function(){
		 	var T = Ext.Toolbar;
	        var pagingItems = [this.first = new T.Button({
	            tooltip: this.firstText,
	            overflowText: this.firstText,
	            iconCls: 'x-tbar-page-first',
	            disabled: true,
	            handler: this.moveFirst,
	            scope: this
	        }), this.prev = new T.Button({
	            tooltip: this.prevText,
	            overflowText: this.prevText,
	            iconCls: 'x-tbar-page-prev',
	            disabled: true,
	            handler: this.movePrevious,
	            scope: this
	        }), '-', this.beforePageText,
	        this.inputItem = new Ext.form.NumberField({
	            cls: 'x-tbar-page-number',
	            allowDecimals: false,
	            allowNegative: false,
	            enableKeyEvents: true,
	            selectOnFocus: true,
	            listeners: {
	                scope: this,
	                keydown: this.onPagingKeyDown,
	                blur: this.onPagingBlur
	            }
	        }), this.afterTextItem = new T.TextItem({
	            text: String.format(this.afterPageText, 1)
	        }), '-', this.next = new T.Button({
	            tooltip: this.nextText,
	            overflowText: this.nextText,
	            iconCls: 'x-tbar-page-next',
	            disabled: true,
	            handler: this.moveNext,
	            scope: this
	        }), this.last = new T.Button({
	            tooltip: this.lastText,
	            overflowText: this.lastText,
	            iconCls: 'x-tbar-page-last',
	            disabled: true,
	            handler: this.moveLast,
	            scope: this
	        }), '-', this.refresh = new T.Button({
	            tooltip: this.refreshText,
	            overflowText: this.refreshText,
	            iconCls: 'x-tbar-loading',
	            handler: this.refresh,
	            scope: this
	        }),'-',
	        this.exportExl = new Ext.SplitButton({
					scope:this,
					text : '导出 Excel',
					pressed : false,
					menu : new Ext.menu.Menu({
						items : [{
							text : '导出当前页 Excel',
							handler : this.onClick2.createDelegate(this,
									["printCurrent"])
						}, {
							text : '导出全部 Excel',
							handler : this.onClick2.createDelegate(this, ["printAll"])
						}]
					}),
					handler :this.onClick2.createDelegate(this,
									["printCurrent"])
				}),
			this.exportPdf = new Ext.SplitButton({
					split:true,
					scope:this,
					text : '导出 Pdf',
					pressed : false,
					menu : new Ext.menu.Menu({
						items : [{
							text : '导出当前页  Pdf',
							handler : this.onClick2.createDelegate(this,
									["printCurrentPDF"])
						}, {
							text : '导出全部 Pdf',
							handler : this.onClick2.createDelegate(this, ["printAllPDF"])
						}]
					}),
					handler :this.onClick2.createDelegate(this,
									["printCurrentPDF"])
				})
	        ];
	        var userItems = this.items || this.buttons || [];
	        if (this.prependButtons) {
	            this.items = userItems.concat(pagingItems);
	        }else{
	            this.items = pagingItems.concat(userItems);
	        }
	        delete this.buttons;
	        if(this.displayInfo){
	            this.items.push('->');
	            this.items.push(this.displayItem = new T.TextItem({}));
	        }
	        Ext.PagingToolbar.superclass.initComponent.call(this);
	        this.addEvents(
	            'change',
	            'beforechange'
	        );
	        this.on('afterlayout', this.onFirstLayout, this, {single: true});
	        this.cursor = 0;
	        this.bindStore(this.store);
	    }
	});
	
	
	Ext.override(Ext.Toolbar.Item, {
			render	 : function(ct,position){
				Ext.Toolbar.Item.superclass.render.call(this,ct,position);
			},
			onRender : function(ct,position) {
				Ext.Toolbar.Item.superclass.onRender.call(this,ct,position);
				var links = this.el.select("a");
				var thisItem = this;
				links = links||[] ;
				links.each(function(link){
					if (link.onclick) {
						var clickTemp = link.onclick;
						link.onclick = function() {
							if (thisItem.el.disabled) {
								return;
							}
							return clickTemp();
						};
					}
				});
			}
		});
	Ext.override(Ext.Toolbar.TextItem, {
			render	 : function(ct,position){
				Ext.Toolbar.TextItem.superclass.render.call(this,ct,position);
			},
			getEventHolder : function(){
		    	var childs = this.el.dom.childNodes ;
		    	for( var i =0,len = childs.length; i<len ; i++){
		    		if( typeof childs[i].onclick == 'function'){
		    			return childs[i] ;
		    		}
		    	}
		    },			
			onRender : function(ct,position) {
			    Ext.Toolbar.TextItem.superclass.onRender.call(this,ct,position);
				// accKey
		        var html = this.el.dom.innerHTML ;
		        if( this.accKeyRe.test(html) ){
			        var accKey = html.replace(this.accKeyRe,'$1')
			        if(accKey){
			        	var key = accKey.replace(/(Ctrl|Shift|Alt)/ig,'').replace(/\+*/g,'');
			        	var holder = this.getEventHolder(); 
			        	if( holder ){
				        	var handler = holder.onclick ;
				        	var item = this.el ;
			        		this.accKeyMap = new Ext.KeyMap(Ext.getDoc(), {
						        key	 : key,
						        stopEvent : true,
						        shift: accKey.contains('Shift'),
						        ctrl : accKey.contains('Ctrl'),
						        alt  : accKey.contains('Alt'),
						        fn	 : function(){
						        	if( !item.disabled ){
							        	handler.call(this.scope||this);
						        	}
						        }
						    });
						    this.accKeyMap.stopEvent = true ;
						    holder.setAttribute('ext:qtip','<span class="acckey-text">{0}</span><br/><span class="acckey">{1}</span>'
						    					.format( holder.innerHTML||'',accKey) );
						    holder.setAttribute('qclass','x-ufida-tip')
			        	}
			        }
		        }
			}
		});
		
		
	
	Ext.override(Ext.Button,{
		onRender : function(ct, position){
			if(!this.template){
	            if(!Ext.Button.buttonTemplate){
	                // hideous table template
	                Ext.Button.buttonTemplate = new Ext.Template(
	                    '<table cellspacing="0" class="x-btn {3}"><tbody class="{4}">',
	                    '<tr><td class="x-btn-tl"><i>&#160;</i></td><td class="x-btn-tc"></td><td class="x-btn-tr"><i>&#160;</i></td></tr>',
	                    '<tr><td class="x-btn-ml"><i>&#160;</i></td><td class="x-btn-mc"><em class="{5}" unselectable="on"><button class="x-btn-text {2}" type="{1}">{0}</button></em></td><td class="x-btn-mr"><i>&#160;</i></td></tr>',
	                    '<tr><td class="x-btn-bl"><i>&#160;</i></td><td class="x-btn-bc"></td><td class="x-btn-br"><i>&#160;</i></td></tr>',
	                    "</tbody></table>");
	                Ext.Button.buttonTemplate.compile();
	            }
	            this.template = Ext.Button.buttonTemplate;
	        }
	        var btn, targs = this.getTemplateArgs();
	        if(position){
	            btn = this.template.insertBefore(position, targs, true);
	        }else{
	            btn = this.template.append(ct, targs, true);
	        }
	        this.btnEl = btn.child(this.buttonSelector);
	        this.mon(this.btnEl, {
	            scope: this,
	            focus: this.onFocus,
	            blur: this.onBlur
	        });
	        this.initButtonEl(btn, this.btnEl);
	        Ext.ButtonToggleMgr.register(this);
	        
	        // handle accKey 
	        if( this.accKey ){
	        	var accKey = this.accKey ;
	        	var handler = this.onClick ;
	        	if( !AccKey.getKeyMap(accKey) ){
		        	var key = accKey.replace(/(Ctrl|Shift|Alt)/ig,'').replace(/\+*/g,'');
		    		this.accKeyMap = new Ext.KeyMap(Ext.getDoc(), {
				        key	 : key,
				        stopEvent : true,
				        shift: accKey.contains('Shift'),
				        ctrl : accKey.contains('Ctrl'),
				        alt  : accKey.contains('Alt'),
				        fn	 : function(k,e){
				        	if( !this.disabled && this.handler ){
				        		e.button = 0
					        	this.handler.call(this.scope||this,e);
				        	}
				        },
				        scope : this
				    });
				    this.accKeyMap.stopEvent = true ;
				    AccKey.register(accKey,this.accKeyMap);
	        	}
			    this.el.dom.setAttribute('title',((this.text||'')+' ')+accKey)
	//		    this.el.dom.setAttribute('qclass','x-ufida-tip')
	        }
		}
	});
	
	/**
	 */
	Ext.override(Ext.FormPanel,{
		initComponent : function(){
	        this.form = this.createForm();
	        Ext.FormPanel.superclass.initComponent.call(this);
	        this.bodyCfg = {
	            tag: 'form',
	            cls: this.baseCls + '-body',
	            method : this.method || 'POST',
	            id : this.formId || Ext.id()
	        };
	        if(this.fileUpload) {
	            this.bodyCfg.enctype = 'multipart/form-data';
	        }
	        this.initItems();
	        this.addEvents(
	            'clientvalidation'
	        );
	        this.relayEvents(this.form, ['beforeaction', 'actionfailed', 'actioncomplete']);
	        if( this.initFocusTraversal){
	        	this.on('afterlayout',this.initFocusTraversal)
	        }
	    }
	});
	
	/**
	 * toolbar中的按钮显示背景图片,	 而pagingTtoolbar中的按钮不显示背景图片
	 */
	Ext.override(Ext.Button,{
		getTemplateArgs : function(){
	        var cls = (this.cls || '');
	        cls += (this.iconCls || this.icon) ? (this.text ? ' x-btn-text-icon' : ' x-btn-icon') : ' x-btn-noicon';
	        if(this.pressed){
	           // cls += ' x-btn-pressed';
	        }
	        return [this.text || '&#160;', this.type, this.iconCls || '', cls, 'x-btn-' + this.scale + ' x-btn-icon-' + this.scale + '-' + this.iconAlign, this.getMenuClass()];
	    }
	})
	Ext.override(Ext.Toolbar,{
		toolbarCls : 'x-toolbar x-icon-toolbar'
	})
	Ext.override(Ext.PagingToolbar,{
		toolbarCls : 'x-toolbar'
	})
	
	/**
	 * 显示Tip时不超出屏幕右边界,避免由于显示tip而出现滚动条
	 */
	Ext.override(Ext.Element,{
		getConstrainToXY : function(el, local, offsets, proposedXY){   
		    var os = {top:0, left:0, bottom:0, right: 0};
	        return function(el, local, offsets, proposedXY){
	            el = Ext.get(el);
	            offsets = offsets ? Ext.applyIf(offsets, os) : os;
	            var vw, vh, vx = 0, vy = 0;
	            if(el.dom == document.body || el.dom == document){
	                vw =Ext.lib.Dom.getViewWidth();
	                vh = Ext.lib.Dom.getViewHeight();
	            }else{
	                vw = el.dom.clientWidth;
	                vh = el.dom.clientHeight;
	                if(!local){
	                    var vxy = el.getXY();
	                    vx = vxy[0];
	                    vy = vxy[1];
	                }
	            }
	            var s = el.getScroll();
	            vx += offsets.left + s.left;
	            vy += offsets.top + s.top;
	            vw -= offsets.right;
	            vh -= offsets.bottom;
	            var vr = vx+vw;
	            var vb = vy+vh;
	            var xy = proposedXY || (!local ? this.getXY() : [this.getLeft(true), this.getTop(true)]);
	            var x = xy[0], y = xy[1];
	            var w = this.dom.offsetWidth, h = this.dom.offsetHeight;
	            var moved = false;
	            if((x + w) > vr){
	                x = vr - w -5;		// 向左移5px,避免超出屏幕右边界
	                moved = true;
	            }
	            if((y + h) > vb){
	                y = vb - h;
	                moved = true;
	            }
	            if(x < vx){
	                x = vx;
	                moved = true;
	            }
	            if(y < vy){
	                y = vy;
	                moved = true;
	            }
	            return moved ? [x, y] : false;
	        };
	    }()
	})
	
	/**
	 * 解决表单中存在隐藏panel时，panel的items无法进行渲染，因而也无法作为表单字段进行提交的问题
	 */
	Ext.override(Ext.Container,{
		forceLayout : true
	});
	
	Ext.override(Ext.menu.Menu,{
		enableScrolling : false
	})
	
	/*//添加事件改回2.0的formPanel
	Ext.override(Ext.form.FormPanel,{onAdd : function(ct, c) {
		if (c.isFormField) {
			this.form.add(c);
		}
	}});*/
	
	
	Ext.override(Ext.Window,{
		// private
	    initTools : function(){
	    	if( this.helpHandler ){
	    		this.addTool({
	                id: 'help',
	                'qtip': this.helpTip,
	                handler: this.helpHandler.createDelegate(this, [])
	            });
	    	}
	        if(this.minimizable){
	            this.addTool({
	                id: 'minimize',
	                handler: this.minimize.createDelegate(this, [])
	            });
	        }
	        if(this.maximizable){
	            this.addTool({
	                id: 'maximize',
	                handler: this.maximize.createDelegate(this, [])
	            });
	            this.addTool({
	                id: 'restore',
	                handler: this.restore.createDelegate(this, []),
	                hidden:true
	            });
	            this.mon(this.header, 'dblclick', this.toggleMaximize, this);
	        }
	        if(this.closable){
	            this.addTool({
	                id: 'close',
	                handler: this[this.closeAction].createDelegate(this, [])
	            });
	        }
	    }
	})
	
	
	if( Ext.isIE ){
		/**
		 * 解决ext3在ie6下columnlayout 存在的宽度计算错误的bug
		 */
		Ext.override(Ext.layout.ColumnLayout,{
		    onLayout : function(ct, target){
		        var cs = ct.items.items, len = cs.length, c, i;
		        if(!this.innerCt){
		            target.addClass('x-column-layout-ct');
		            this.innerCt = target.createChild({cls:'x-column-inner'});
		            this.innerCt.createChild({cls:'x-clear'});
		        }
		        this.renderAll(ct, this.innerCt);
		        var size = Ext.isIE && target.dom != Ext.getBody().dom ? target.getStyleSize() : target.getViewSize();
		        if(size.width < 1 && size.height < 1){ // display none?
		            return;
		        }
		        var w = size.width - target.getPadding('lr') - this.scrollOffset,
		            h = size.height - target.getPadding('tb'),
		            pw = w;
		        this.innerCt.setWidth(w);
		        this.innerCt.dom.style.width = "100%";	// fix ie6 columnlayout bug
		        
		        // some columns can be percentages while others are fixed
		        // so we need to make 2 passes
		        for(i = 0; i < len; i++){
		            c = cs[i];
		            if(!c.columnWidth){
		                pw -= (c.getSize().width + c.getEl().getMargins('lr'));
		            }
		        }
		        pw = pw < 0 ? 0 : pw;
		        for(i = 0; i < len; i++){
		            c = cs[i];
		            if(c.columnWidth){
		                c.setSize(Math.floor(c.columnWidth*pw) - c.getEl().getMargins('lr'));
		                if(c.dom){
		                	c.dom.style.width = "100%";
		                }
		            }
		        }
		    }
		});
	}
}

/**
 * *********************************************************************
 * 升级 Ext3.0  END
 * *********************************************************************
 */
Ext.override(Ext.form.Action.Submit,{
	run : function(){
        var o = this.options;
        var method = this.getMethod();
        var isGet = method == 'GET';
        if(o.clientValidation === false || this.form.isValid()){
            Ext.Ajax.request(Ext.apply(this.createCallback(o), {
                form:this.form.el.dom,
                url:this.getUrl(isGet),
                method: method,
                headers: o.headers,
                params:!isGet ? this.getParams() : null,
                isUpload: this.form.fileUpload
            }));
        }else if (o.clientValidation !== false){ // client validation failed
            this.failureType = Ext.form.Action.CLIENT_INVALID;
            this.form.afterAction(this, false);
        }
    }
});
function debug(){
//	return;
	var msgArr = [] ;
	var args = arguments ;
	for( var i =0,len = arguments.length;i<len;i++){
		msgArr.push(arguments[i]);
	}
	if(!Ext.isReady){
		return// alert(msgArr.join(''))
	}
	var debugWin = Ext.getCmp('debugWindow');
	if( debugWin && debugWin.el && !debugWin.el.isVisible()){
		debugWin.show();
		debugWin.el.alignTo(Ext.getBody(),'tl-bl')
	}
	if( debugWin && debugWin.el ){
		try{
			debugWin.debug(msgArr.join(''))
		}catch(e){}
	}else{
		setTimeout(function(){
			debug.apply(this,args)
		},1000)
	}
}
/*************************************************
 *  覆盖Ext.data.Connection.request函数,
 *  AJAX请求时,后台抛出超时或重复登陆,则打出提示并退出系统
 *  除此外,无其他修改  add by yzt 20091202
 ***********************************************/
Ext.override(Ext.data.Connection, {request:function(o){
			var BEFOREREQUEST = "beforerequest",
	        REQUESTCOMPLETE = "requestcomplete",
	        REQUESTEXCEPTION = "requestexception",
	        UNDEFINED = undefined,
	        LOAD = 'load',
	        POST = 'POST',
	        GET = 'GET',
	        WINDOW = window;
	        
	        // private
		    function handleResponse(response){
		        this.transId = false;
		        var options = response.argument.options;
		        response.argument = options ? options.argument : null;
		        /**** AJAX请求时,后台抛出超时或重复登陆,则打出提示并推出系统 add by yzt 20091202***/
		        var obj = Ext.decode(response.responseText)
		        if(obj && obj.overtime){
		        	return displayMessageBox('提示', obj.message,Ext.MessageBox.OK, function() {
						window.location.href = RELOGIN_PAGE
					});
		        }
		        /**** END AJAX请求时,后台抛出超时或重复登陆,则打出提示并推出系统 add by yzt 20091202***/
		        this.fireEvent(REQUESTCOMPLETE, this, response, options);
		        if(options.success){
		            options.success.call(options.scope, response, options);
		        }
		        if(options.callback){
		            options.callback.call(options.scope, options, true, response);
		        }
		    }
		
		    // private
		    function handleFailure(response, e){
		        this.transId = false;
		        var options = response.argument.options;
		        response.argument = options ? options.argument : null;
		        this.fireEvent(REQUESTEXCEPTION, this, response, options, e);
		        if(options.failure){
		            options.failure.call(options.scope, response, options);
		        }
		        if(options.callback){
		            options.callback.call(options.scope, options, false, response);
		        }
		    } 
		    
            var me = this;
            if(me.fireEvent(BEFOREREQUEST, me, o)){
                if (o.el) {
                    if(!Ext.isEmpty(o.indicatorText)){
                        me.indicatorText = '<div class="loading-indicator">'+o.indicatorText+"</div>";
                    }
                    if(me.indicatorText) {
                        Ext.getDom(o.el).innerHTML = me.indicatorText;                        
                    }
                    o.success = (Ext.isFunction(o.success) ? o.success : function(){}).createInterceptor(function(response) {
                        Ext.getDom(o.el).innerHTML = response.responseText;
                    });
                }
                
                var p = o.params,
                    url = o.url || me.url,                
                    method,
                    cb = {success: handleResponse,
                          failure: handleFailure,
                          scope: me,
                          argument: {options: o},
                          timeout : o.timeout || me.timeout
                    },
                    form,                    
                    serForm;                    
                  
                     
                if (Ext.isFunction(p)) {
                    p = p.call(o.scope||WINDOW, o);
                }
                                                           
                p = Ext.urlEncode(me.extraParams, Ext.isObject(p) ? Ext.urlEncode(p) : p);    
                
                if (Ext.isFunction(url)) {
                    url = url.call(o.scope || WINDOW, o);
                }
    
                if((form = Ext.getDom(o.form))){
                    url = url || form.action;
                     if(o.isUpload || /multipart\/form-data/i.test(form.getAttribute("enctype"))) { 
                         return doFormUpload.call(me, o, p, url);
                     }
                    serForm = Ext.lib.Ajax.serializeForm(form);                    
                    p = p ? (p + '&' + serForm) : serForm;
                }
                
                method = o.method || me.method || ((p || o.xmlData || o.jsonData) ? POST : GET);
                
                if(method === GET && (me.disableCaching && o.disableCaching !== false) || o.disableCaching === true){
                    var dcp = o.disableCachingParam || me.disableCachingParam;
                    url = Ext.urlAppend(url, dcp + '=' + (new Date().getTime()));
                }
                
                o.headers = Ext.apply(o.headers || {}, me.defaultHeaders || {});
                
                if(o.autoAbort === true || me.autoAbort) {
                    me.abort();
                }
                 
                if((method == GET || o.xmlData || o.jsonData) && p){
                    url = Ext.urlAppend(url, p);  
                    p = '';
                }
                return (me.transId = Ext.lib.Ajax.request(method, url, cb, p, o));
            }else{                
                return o.callback ? o.callback.apply(o.scope, [o,UNDEFINED,UNDEFINED]) : null;
            }
        }});